2009-05-06 14 views
6

Estoy a punto de desarrollar algunas tomas de cosas relacionadas en C++ y me gustaría que el software sea tan portátil entre Windows y Linux como sea posible desde el principio (lo que es más portátil es difícil.)Winsock 2 portabilidad

He visto diferentes bibliotecas, hay una para C++ desde alhem.net y, por supuesto, hay boost :: asio. boost :: asio parece muy prometedor pero sería una gran dependencia para aplicaciones tan pequeñas.

¿Vale la pena escribir las cosas yo solo o debería simplemente usar una biblioteca? Si lo hago yo mismo, ¿cuáles serían los principales escollos?

Respuesta

3

winsocks no son muy compatibles con los zócalos Posix:

  • En winsocks una toma es de tipo SOCKET. En Posix es simplemente un descriptor de archivo (int), en el que puede realizar llamadas normales read() y write().
  • No devuelven los errores de la misma manera.
  • No admiten algunas opciones en recv() y send().
  • Debe inicializar y unificar la biblioteca Winsocks con dos funciones especiales.
  • No creo que pueda cerrar los zócalos de Windows con shutdown() o close(). Es algo así como closesocket() en su lugar.

Debe haber más diferencias, pero eso es lo que puedo recordar en este momento. Si desea portabilidad con Winsocks, tendrá una pequeña biblioteca para cerrar un socket, imprimir un mensaje de error, etc.

Probablemente vaya con boost::asio, personalmente (nunca lo he usado, sin embargo).

+0

Ok, veré lo que hago. Boost :: asio también tiene una interfaz ICMP que es muy buena, así que actualmente parece que usaré eso. – Skurmedel

+0

shutdown () es una función válida para los sockets de Windows. ¿Tiene razón en que se debe usar closesocket()? –

+1

closesocket es solo la versión de Windows de cierre, para que no tengan que sobrecargar la función de cierre. t TIENE que cerrar un archivo/socket, pero si no lo hace, puede perder datos. WSAGetLastError es solo la función de Windows para obtener errno, ya que la API de Windows no soportaba errno de la misma manera. Y para los sockets, POSIX admite versiones de "envío" y "recv" de lectura y escribir. – david

1

Honestamente, usaría boost :: asio como primera preferencia. Si realmente quiere ensuciarse con la API de sockets, puede usar la API estándar de sockets de estilo BSD tanto en Windows como en Linux. Es solo que en Windows deberá vincular (e inicializar) Winsock2, mientras que en Linux no tendrá una biblioteca separada para enlazar.

+0

Gracias por el asesoramiento. +1 esto, solo puede marcar una respuesta :( – Skurmedel

1

¿Cuántas cosas del conector va a utilizar? He hecho varias aplicaciones donde las cosas del socket eran de muy alto nivel (abrir, leer, escribir) y funcionaban perfectamente desde Windows hasta Linux. Si es más que eso, ve con impulso.

+0

Al principio, sería de muy bajo nivel, como abrir una conexión, escribir algo, leer, salir. Probablemente crezca para incluir cosas Http. – Skurmedel

+0

Gracias por el consejo . +1 esto, solo puede marcar una respuesta :( – Skurmedel

5

He desarrollado algunas envolturas portátiles alrededor de los enchufes. Asegúrate de no ir por el sendero sin retorno que está constituido por eventos de WinSock2.Aparte de eso, en mi opinión, las diferencias más grandes son:

  • para iniciar la red en Windows, es necesario llamar a ::WSAStartup(), para apagarlo en Windows, ejecute ::WSACleanup(); en Linux no hacer nada,
  • close() en Linux es closesocket() en Windows,
  • tamaños de búfer predeterminado difieren entre los dos pilotos y sistemas operativos, así que asegúrese de ajustar usando SO_RCVBUF y SO_SNDBUF,
  • SO_REUSEADDR roba la dirección en Windows , permite la reapertura frecuente en Linux; lo que probablemente sólo desea utilizar esta bandera en Linux,
  • haciendo una toma sin bloqueo utiliza ::ioctlsocket() en Windows, Linux en ::fcntl(),
  • los archivos de cabecera son diferentes, <sys/socket.h> y amigos en Linux, <WinSock.h> en Windows,
  • ir portátil, la forma más fácil es probablemente usar ::select() que esperar para recibir datos,
  • fd_set s son totalmente diferentes en Windows/Linux; esto solo es relevante si necesita optimizar la inicialización de fd_set s, como al agregar/eliminar sockets arbitrarios,
  • en Windows, cualquier hilo que cuelgue en el socket se libera con un código de error cuando el socket está cerrado, en Linux el hilo sigue esperando. Si el hilo está bloqueando el zócalo, por ejemplo, ::recvfrom(), puede considerar usar ::sendto() para liberar el hilo que se detiene en Linux.

Todo lo demás que he necesitado acaba de salir del låda.

+0

Consejo muy útil. Tackar och bugar;). – Skurmedel

+0

¡Eres más välkommen! –

2

Tome un vistazo a la biblioteca "entorno de comunicaciones adaptativa" (ACE): (ACE Home Page) Proporciona algunas abstracciones agradable y una gran flexibilidad de todo enrollado en una biblioteca portátil que es compatible con Windows, MacOS y Linux. Tiene una curva de aprendizaje un poco empinada, pero obtuve muy buen valor de ella.

+0

Gracias por la sugerencia. – Skurmedel

Cuestiones relacionadas