c ++ cómo usar seleccionar para ver si un socket se ha cerrado

¿Puede alguien darme un ejemplo de cómo usar select () para ver si un cliente ha cerrado la conexión en un socket?

FYI. Estoy usando linux

¡Gracias!

El siguiente fragmento primero verifica si el socket está marcado como legible (que es cuando está cerrado) y luego si realmente hay algo que leer.

#include  #include  #include  #include  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; } 

No es necesario hacer una select() seguida de ioctl() . En su lugar, puede hacer un vistazo no bloqueante en el socket para ver si devuelve 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; } 

Si obtiene una notificación de lectura y la lectura devuelve 0 bytes, el cliente ha salido limpiamente. Si no, recibirá una notificación de excepción.

Si el cliente ha cerrado limpiamente, debe recibir una notificación de que READ no se bloqueará y se marcará EXCEPCIÓN (tercer conjunto).

Si el cliente ha cerrado abortivamente, no lo sabe. Esto está sujeto al problema de los dos generales.