2010-06-22 29 views
17

Tengo una aplicación que establece una conexión de socket en un puerto número 5005 con otro dispositivo (dispositivo de hardware con un servidor web).recv() función de socket que devuelve datos con longitud como 0

Ahora, si mi dispositivo de hardware se desconecta, entonces pierdo la conexión con el dispositivo.

  1. ¿Quiere decir esto que la toma que estaba aplicados hasta la fecha no es válida.

  2. Recibo algún mensaje especial como carácter nulo o algo cuando ocurre esta desconexión.

  3. Si la conexión de socket que estaba haber convirtió entonces ¿por qué no válida doesnt el recv() función de socket tiro y SOCKET_ERROR. En cambio, , ¿por qué recibo datos de 0 de longitud?

Gracias

+0

¿Ha llamado shutdown() en el lado remoto? Esto hará que recv return 0: http://stackoverflow.com/questions/2843277/c-winsock-p2p/2920787#2920787 – Default

Respuesta

31

Cuando recv devuelve un valor de 0 que significa la conexión ha sido cerrada.

Ver las recv man page:

Estas llamadas devuelven el número de bytes recibidos, o -1 si ocurre un error . El valor de retorno será 0 cuando el igual ha realizado un cierre ordenado de .

En respuesta a la pregunta n. ° 1, sí, el socket no es válido. Debe crear un nuevo socket y conexión para futuras comunicaciones.

Editar

Ahora, como valdo señala más adelante, también existe la posibilidad de tener una conexión TCP medio cerrado en el que no podrá recibir más, pero se puede seguir escribiendo a la toma hasta que se Ya he terminado de enviar tus datos. Vea este artículo para más detalles: TCP Half-Close. Sin embargo, no parece que tengas esta situación.

En respuesta a la pregunta n. ° 2, hay básicamente dos formas de detectar un socket cerrado. Esto supone que el socket pasó por un apagado ordenado, lo que significa que el par llamado shutdown o close.

El primer método es leer desde el zócalo, en cuyo caso obtendrá un valor de retorno de 0. El otro método es escribir en el zócalo, lo que provocará que la señal SIG_PIPE se arroje indicando una tubería rota.

Con el fin de evitar la señal, puede establecer la opción MSG_NOSIGNAL toma en cuyo caso habría send devolver -1 y establecer errno a EPIPE.

+0

Entonces, lo que tengo que hacer es si obtengo un valor de retorno de 0, entonces necesito cerrar eso toma y abre otra toma, ¿verdad? – ckv

+0

@cvk - Correcto. –

+1

¿Por qué alguien marcó esta respuesta? –

2

Si recv devuelve 0 esto significa que el par ha cerrado el socket.

recv no se lanzará porque es una función C.

Si hay un error, recv devolverá -1. En ese caso, su aplicación debe verificar el tipo de error. Tenga en cuenta que un retorno de -1 no implica que el par haya cerrado su socket.

1

Dado que está hablando con un servidor web, asumiré que está utilizando sockets TCP.

Para responder:

  1. sockets no dejan de ser válidas debido a una falta de conexión; simplemente entran en un estado desconectado. Todavía es seguro llamar operaciones de socket en ellos.

  2. No se reciben mensajes especiales cuando ocurre la desconexión. Si llama al recv() de forma bloqueada, regresará cuando se desconecte, y el número de bytes devueltos por la llamada no coincidirá con el número de bytes que solicitó.

  3. no hay realmente una respuesta a esto - es la forma en la API de socket fue implementado originalmente, y que está pegado con esa aplicación a la todos implementa Berkley Sockets.

3

Supongo que está utilizando TCP para comunicarse con su dispositivo.

  1. El zócalo en sí sigue siendo "válido", sin embargo, la conexión se perdió.

  2. Usted obtiene un valor de retorno de 0 a recv() cuando la conexión fue cerrada por el otro host (wether esta desconexión era gracioso o no, no importa)

  3. funciones de socket son como C funciones: Don 't throw porque pueden usarse en los programas C, donde existen excepciones no.

8

De acuerdo con Robert S. Barnes. Excepto la afirmación de que el socket ahora es "inválido".

Sigue siendo válido. Puedes usarlo. Incluso puede enviar datos al par. Lo único que no puede hacer es llamar al recv.

+1

+1 De acuerdo, me olvidé de la posibilidad de un medio cierre. Actualizaré mi respuesta. –

+0

Quería señalar que esto depende de si el interlocutor llamó 'close', o lo hizo a medias al llamar' shutdown' con el indicador 'SHUT_WR'. Consulte la página de manual de 'shutdown': http://www.kernel.org/doc/man-pages/online/pages/man2/shutdown.2.html –

Cuestiones relacionadas