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.
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With