Detecting whenever socket disconnected using select()

10,523

When a socket closes it becomes "readable" but calling recv will return 0 bytes. Using select you can tell when the socket can be read then when reading it if recv returns 0 then you know it has closed.

Your comment "bytes available" isn't exactly accurate. The socket may be read from however, if it is closed there will be no bytes available.

else if(result > 0 && FD_ISSET(this->sockfd, &fd))
{
    return 1; // bytes available.
}

In non-blocking sockets, recv will return -1 and set errno to EWOULDBLOCK (or EAGAIN) if there is no data and the socket is not closed.

Share:
10,523
user2399415
Author by

user2399415

Updated on July 03, 2022

Comments

  • user2399415
    user2399415 almost 2 years

    I'm trying to detect whenever client has been disconnected with select() function. The problem is that, I don't quite much understood how select() does work. I'm using following code, can you tell me what I'm doing wrong and/or how to detect if client is disconnected? I'm using non-blocking sockets.

    int Network::bytesAvailable()
    {
        long bytes = 0;
    
        if(ioctl(this->sockfd, FIONREAD, &bytes) < 0)
        {
            printf("ERROR: Network:bytesAvailable: ioctl() call failed.\n");
            return -1;
        }
    
        return bytes;
    }
    
    NetworkStatus Network::status()
    {
        struct timeval tv;
        fd_set  fd;
        int result = 0;
    
        tv.tv_sec  = 5;
        tv.tv_usec = 0;
    
        FD_ZERO(&fd);
        FD_SET(this->sockfd, &fd);
    
        result = select(this->sockfd + 1, &fd, 0, 0, &tv);
    
        if(result && !this->bytesAvailable())
        {
            return -1; // disconnected, I'm guessing this is definitely WRONG.
        }
        else if(result > 0 && FD_ISSET(this->sockfd, &fd))
        {
            return 1; // bytes available.
        }
        else if(!result)
        {
            return 0; // timeout
        }
    
        return -1; // select() call failed.
    }
    
  • user2399415
    user2399415 almost 11 years
    AFAIK on non-blocking sockets, it's not correct, because recv can return 0 (no data has been received yet).