[ACCEPTED]-c++ how to use select to see if a socket has closed-select

Accepted answer
Score: 21

The below snippet first checks if the socket 3 is marked readable (which it is when closed) and 2 then if there's actually anything to be 1 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;
}
Score: 9

You don't need to do a select() followed by ioctl(). You 2 can instead do a non-blocking peek on the 1 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;
}
Score: 4

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

More Related questions