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!

¿Fue útil?

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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top