reaccionar ante la desconexión del cliente en linux

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;
};

preguntado el 12 de junio de 12 a las 11:06

¿Está utilizando select () o epol ()? -

Si está utilizando seleccionar, aquí hay una respuesta: stackoverflow.com/q/283375/1158895 -

3 Respuestas

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 0en 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

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

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 or haz tu propia pregunta.