有人能为我提供一个如何使用select()查看客户端是否已关闭套接字连接的示例吗?
FYI。我正在使用linux。
谢谢!
答案 0 :(得分:21)
下面的代码片段首先检查套接字是否标记为可读(在关闭时是否可读),然后确定是否有任何要读取的内容。
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ioctl.h>
bool isclosed(int sock) {
fd_set rfd;
FD_ZERO(&rfd);
FD_SET(sock, &rfd);
timeval tv = { 0 };
select(sock+1, &rfd, 0, 0, &tv);
if (!FD_ISSET(sock, &rfd))
return false;
int n = 0;
ioctl(sock, FIONREAD, &n);
return n == 0;
}
答案 1 :(得分:8)
您不需要select()
后跟ioctl()
。您可以在套接字上执行非阻塞查看以查看它是否返回0
。
bool isclosed (int sock) {
char x;
interrupted:
ssize_t r = ::recv(sock, &x, 1, MSG_DONTWAIT|MSG_PEEK);
if (r < 0) {
switch (errno) {
case EINTR: goto interrupted;
case EAGAIN: break; /* empty rx queue */
case ETIMEDOUT: break; /* recv timeout */
case ENOTCONN: break; /* not connected yet */
default: throw(errno);
}
}
return r == 0;
}
答案 2 :(得分:4)
如果您收到读取通知并且读取返回0字节,则客户端已完全退出。如果没有,您将收到例外通知。
答案 3 :(得分:1)
如果客户端已经干净地关闭,您应该收到READ不会阻止的通知,并且标记了EXCEPTION(第三组)。
如果客户已经中止了,你就不知道了。这是两个将军的问题。