c++ how to use select to see if a socket has closed

前端 未结 3 736
失恋的感觉
失恋的感觉 2020-11-30 06:19

Can someone provide me an example of how to use select() to see if a client has closed the connection on a socket?

FYI. I\'m using linux.

Thanks!

相关标签:
3条回答
  • 2020-11-30 06:32

    The below snippet first checks if the socket is marked readable (which it is when closed) and then if there's actually anything to be read.

    #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;
    }
    
    0 讨论(0)
  • 2020-11-30 06:44

    You don't need to do a select() followed by ioctl(). You can instead do a non-blocking peek on the socket to see if it returns 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;
    }
    
    0 讨论(0)
  • 2020-11-30 06:48

    If you get a read notification and the read returns 0 bytes the client has exited cleanly. If not you will get an exception notification.

    0 讨论(0)
提交回复
热议问题