que - socket cliente-servidor en c linux
FunciĆ³n de socket recv() que devuelve datos con longitud como 0 (6)
Dado que estás hablando con un servidor web, asumiré que estás usando sockets TCP.
Contestar:
Los sockets no se vuelven inválidos debido a una desconexión; simplemente entran en un estado desconectado. Todavía es seguro llamar a las operaciones de socket en ellos.
No recibe ningún mensaje especial cuando se produce la desconexión. Si llama a
recv()
de forma bloqueada, volverá cuando se desconecte, y el número de bytes devueltos por la llamada no coincidirá con el número de bytes que solicitó.Realmente no hay una respuesta para esto: es cómo se implementó originalmente la API socket, y estamos atascados con esa implementación como todos implementan Berkley Sockets.
Tengo una aplicación que estableció una conexión de socket en un número de puerto 5005 con otro dispositivo (dispositivo de hardware con un servidor web).
Ahora, si mi dispositivo de hardware se desconecta, pierdo la conexión con el dispositivo.
¿Significa esto que el socket que estaba usando hasta ahora no es válido?
¿Aparece algún mensaje especial como un carácter nulo o algo cuando ocurre esta desconexión?
- Si la conexión de socket estaba siendo inválida, entonces ¿por qué la función de socket recv () no se lanzó y SOCKET_ERROR? En cambio, ¿por qué recibo datos de 0 de longitud.
Gracias
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 puedes enviar datos al par. Lo único que no se puede hacer con eso es la llamada recv
.
Para corregir numerosos errores en las respuestas existentes:
- ¿Significa esto que el socket que estaba usando hasta ahora no es válido?
No. Significa que el interlocutor ha cerrado la conexión o la ha cerrado para que salga de su extremo. Tu zócalo sigue siendo válido. Puedes volver a llamar a recv()
, pero todo lo que obtendrás es otro cero. También puede llamar a send()
en él, y si el interlocutor solo ha cerrado la conexión para la salida, se enviarán los datos.
- ¿Aparece algún mensaje especial como un carácter nulo o algo cuando ocurre esta desconexión?
No, obtienes un valor de retorno cero de recv()
. Para eso está. Se entrega fuera de banda, no en el búfer de datos.
- Si la conexión de socket que tenía se convirtió en inválida, entonces ¿por qué la función de socket
recv()
no serecv()
Porque es una API de C, y no hay throws
en C, ni tampoco en las llamadas al sistema de Unix.
y SOCKET_ERROR.
Porque no es un error.
En cambio, ¿por qué recibo datos de 0 de longitud.
Usted no ''recibe datos de 0 de longitud''. Recibe un valor de retorno de cero en lugar de datos.
Si recv devuelve 0, esto significa que el par ha cerrado el socket.
recv no lanzará porque es una función de C.
Si hay un error recv devolverá -1. En cuyo caso su aplicación tiene que comprobar el tipo de error. Tenga en cuenta que un retorno de -1 no implica que el par haya cerrado su socket.
Supongo que estás usando TCP para comunicarte con tu dispositivo.
El socket en sí sigue siendo "válido", sin embargo, se perdió la conexión.
Obtendrá un valor de retorno de 0 para
recv()
cuando la conexión fue cerrada por el otro host (ya sea que esta desconexión fue correcta o no importa)Las funciones de socket son como las funciones de
C
: no se lanzan porque se pueden usar en programas deC
, donde no existen excepciones.
Cuando recv
devuelve un valor de 0, significa que la conexión se ha cerrado.
Ver la página de manual de recv
:
Estas llamadas devuelven el número de bytes recibidos, o -1 si ocurrió un error. El valor de retorno será 0 cuando el interlocutor haya realizado un cierre ordenado.
En respuesta a la pregunta # 1, sí, el socket ahora no es válido. Debe crear un nuevo zócalo y conexión para futuras comunicaciones.
Editar
Ahora, como valdo señala a continuación, también existe la posibilidad de tener una conexión TCP semicerrada en la que no puede recibir más pero puede seguir escribiendo en el socket hasta que haya terminado de enviar sus datos. Consulte este artículo para obtener más detalles: TCP medio cierre . Aunque no parece que tengas esta situación.
En respuesta a la pregunta # 2, hay básicamente dos formas de detectar un socket cerrado. Esto supone que el zócalo pasó por un cierre ordenado, lo que significa que el par llamado shutdown
o close
.
El primer método es leer desde el socket, en cuyo caso obtendrá un valor de retorno de 0. El otro método es escribir en el socket, lo que provocará que la señal SIG_PIPE se emita indicando un conducto roto.
Para evitar la señal, puede configurar la opción de socket MSG_NOSIGNAL
, en cuyo caso el send
devolverá -1 y establecerá errno
en EPIPE
.