c ++如何使用select查看套接字是否已关闭

时间:2011-04-12 18:52:04

标签: c++ linux sockets select

有人能为我提供一个如何使用select()查看客户端是否已关闭套接字连接的示例吗?

FYI。我正在使用linux。

谢谢!

4 个答案:

答案 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(第三组)。

如果客户已经中止了,你就不知道了。这是两个将军的问题。