Enviar TCP no vuelve causa proceso de estrellarse
Pregunta
Si un servidor TCP y el cliente están conectados, me gustaría para determinar cuando el cliente ya no está conectado. Pensé que simplemente puede hacer esto mediante el intento de enviar un mensaje al cliente y una vez send () devuelve con un -1, entonces me puedo derribar el zócalo. Esta implementación funciona Encuentra en Windows, pero el momento en que trate de hacer esto en Linux con sockets BSD, la llamada a send () en la aplicación del lado del servidor hace que mi aplicación de servidor para bloquearse si el cliente ya no está conectado. Ni siquiera se devuelve un -1 ... simplemente termina el programa.
Por favor, explique por qué ocurre esto. Gracias de antemano!
Solución
Esto es causado por la señal SIGPIPE. Ver send(2)
:
La función 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 la toma es de SOCK_STREAM tipo o SOCK_SEQPACKET y la bandera MSG_NOSIGNAL no está establecido, la señal SIGPIPE se genera para el subproceso 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
a EPIPE
en esta situación.
Otros consejos
Es necesario hacer caso omiso de la señal SIGPIPE. Si ocurre un error de escritura en un socket, con su proceso de SIGPIPE conseguir, y el comportamiento por defecto de esa señal es matar el proceso. Escribir código de red en * nix normalmente se desea:
signal(SIGPIPE,SIG_IGN);