2009-08-25 17 views
8

Si un servidor tcp y el cliente están conectados, me gustaría determinar cuándo el cliente ya no está conectado. Pensé que simplemente podía hacer esto al intentar enviar un mensaje al cliente y una vez que send() regrese con un -1, puedo derribar el socket. Esta implementación funciona en Windows, pero en el momento en que intento hacerlo en Linux con sockets BSD, la llamada a send() en la aplicación del servidor hace que la aplicación de mi servidor se bloquee si el cliente ya no está conectado. Ni siquiera devuelve un -1 ... solo termina el programa.Envío TCP no devuelve causa de bloqueo proceso

Explique por qué sucede esto. ¡Gracias por adelantado!

Respuesta

13

Esto es causado por la señal SIGPIPE. Ver send(2): función

El send() fallará si:
[EPIPE] La toma se cierra para escribir, o el zócalo esté en modo conexión y ya no está conectado. En este último caso, y si el socket es de tipo SOCK_STREAM o SOCK_SEQPACKET y el indicador MSG_NOSIGNAL no está configurado, la señal SIGPIPE se genera a la cadena de llamada.

Esto se puede evitar mediante el uso de la bandera MSG_NOSIGNAL en la llamada send(), o haciendo caso omiso de la señal SIGPIPE con signal(SIGPIPE, SIG_IGN) al comienzo de su programa. Entonces la función send() devolverá -1 y establecerá errno en EPIPE en esta situación.

2

Debe ignorar la señal SIGPIPE. Si ocurre un error de escritura en un socket, su proceso con obtener SIGPIPE, y el comportamiento predeterminado de esa señal es matar su proceso. Escribir código de red en * nix generalmente quiere:

signal(SIGPIPE,SIG_IGN); 
Cuestiones relacionadas