我试图检测客户端何时与select()函数断开连接.问题是,我不太了解select()是如何工作的.我正在使用以下代码,你能告诉我我做错了什么和/或如何检测客户端是否断开连接?
我正在使用非阻塞套接字.
我正在使用非阻塞套接字.
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,&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. }
解决方法
当套接字关闭时,它变为“可读”但调用recv将返回0字节.使用select你可以知道什么时候可以读取套接字然后在读取时如果recv返回0然后你知道它已经关闭.
您的评论“可用字节数”并不完全准确.但是,可以从中读取套接字,如果它已关闭,则不会有可用的字节.
else if(result > 0 && FD_ISSET(this->sockfd,&fd)) { return 1; // bytes available. }
在非阻塞套接字中,如果没有数据且套接字未关闭,则recv将返回-1并将errno设置为EWOULDBLOCK(或EAGAIN).