reaccionar ante la desconexión del cliente en linux
Frecuentes
Visto 750 veces
0
Estoy escribiendo un demonio de socket simple que escucha un puerto y lee los datos entrantes. Funciona bien hasta que elijo desconectar un cliente del servidor... entonces entra en un bucle infinito recv() devuelve el último paquete que nunca llega a -1. Mi pregunta es ¿cómo puedo detectar que el cliente se ha desconectado y cerrar el hilo/socket el
Mi hilo es el siguiente:
void * SocketHandler(void* lp){
int * csock = (int*)lp;
int test = 0;
char buffer[1024];
int buffer_len = 1024;
int bytecount,ierr;
memset(buffer,0,buffer_len);
while (test == 0)
{
if ((bytecount = recv(*csock, buffer, buffer_len, 0))== -1){
close(csock);
free(csock);
test++;
return 0;
}
else
{
syslog(LOG_NOTICE,"%s",buffer);
}
}
return 0;
};
3 Respuestas
1
Un encaje bien cerrado terminará en un ZERO
leer, mientras que una conexión rota es un estado de error que regresa -1
. Necesitas atrapar el 0
devolución de su recv.
Respondido el 12 de junio de 12 a las 11:06
En realidad, no, cuando solo está leyendo de él, puede terminar fácilmente en un estado en el que el sistema aún considera que el zócalo está abierto. - Simon Toth
@Let_Me_Be Sospecho que te refieres al estado "roto"; por supuesto, esto es una propiedad de TCP/IP. El estado de "desconexión limpia" está garantizado para volver 0
en cualquier sistema operativo cuerdo - Eugen Riek
Estoy bastante seguro de que la implementación de Linux no garantiza esto incluso en desconexiones limpias, pero sí, cuando las estrellas están en la posición correcta, debería obtener 0. - Simon Toth
Bueno el 0
es lo que está picando el OP... en Linux. - Eugen Riek
Oh sí, no me di cuenta de la == -1
:-D - Simon Toth
0
Lo que sucede aquí es que es posible que su extremo no detecte el hecho de que el zócalo está muerto (especialmente, si solo está leyendo).
Lo que puede hacer es configurar keepalive en el socket. Esto activará las comprobaciones periódicas de la actividad del zócalo. Pero no espere reacciones rápidas, el tiempo de espera predeterminado es de unos 20 minutos.
i = 1;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i));
Otra opción es hacer su propia comunicación de mantenimiento.
Respondido el 12 de junio de 12 a las 11:06
0
recv()
indicará un apagado adecuado del enchufe devolviendo 0
(Véase el página de manual para detalles). regresará -1
si y solo si ocurriera un error. deberías revisar errno
para el error exacto, ya que puede o no indicar que la conexión falló (EINTR
, EAGAIN
or EWOULDBLOCK
[se supone que los sockets no bloqueantes] serían errores recuperables).
Nota al margen: no hay necesidad de pasar el fd
del socket como puntero y dado que está devolviendo un void *
es posible que desee cambiar return 0
a return NULL
(solo por legibilidad).
Respondido el 12 de junio de 12 a las 11:06
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas linux multithreading sockets or haz tu propia pregunta.
¿Está utilizando select () o epol ()? - Brady
Si está utilizando seleccionar, aquí hay una respuesta: stackoverflow.com/q/283375/1158895 - Brady