Messages in this thread | | | Date | Fri, 18 Feb 2000 11:57:20 -0500 (EST) | From | "Richard B. Johnson" <> | Subject | Network socket disconnect unreliable |
| |
When a network socket disconnects, this fact can't presently be reliably detected when using select. The exception bit is set, but this gets set occasionly even though there was not a disconnect. This gets set everytime somebody performs an ioctl() on the file discriptor or otherwise changes the mode of the file discriptor.
I tried to use fstat() to see if the file-descriptor was still valid when the exception occurs. It turns out to always be valid even though the socket has been closed!
Code snippet......
The ERRORS() macro logs events and then calls exit(EXIT_FAILURE); The rest of the stuff is standard.
sfd = MAX(fd, ma) +1; FD_ZERO(&mem->rfds); FD_ZERO(&mem->efds); FD_SET(fd, &mem->rfds); FD_SET(ma, &mem->rfds); FD_SET(fd, &mem->efds); FD_SET(ma, &mem->efds); while(select(sfd, &mem->rfds, NULL, &mem->efds, NULL) > 0) { if(FD_ISSET(ma, &mem->efds)) if(fstat(ma, &mem->stat) < 0) ERRORS(Fstat); if(FD_ISSET(fd, &mem->efds)) if(fstat(fd, &mem->stat) < 0) ERRORS(Fstat); if(FD_ISSET(fd, &mem->rfds))
[Snipped standard R/W stuff] {...............}
FD_ZERO(&mem->rfds); FD_ZERO(&mem->efds); FD_SET(fd, &mem->rfds); FD_SET(ma, &mem->rfds); FD_SET(fd, &mem->efds); FD_SET(ma, &mem->efds); }
So, when a socket fd disconnects, this just spins <forever>. The fd is still considered valid! Of course if I read or write to the socket, it will return an error, but I can't just abitrarily do this or I will corrupt data if the socket has not been disconnected.
So, how am I supposed to know if the socket was disconnected? There are of course hacks. I can just count the number of times that this thing looped without finding anything to do and then exit if it's obvious that it's hung.
FYI on my Sun, fstat() on a closed network socket returns -1 and errno is set to EBADF. On Linux, the network socket is still "good" even though the client has disconnected.
Cheers, Dick Johnson
Penguin : Linux version 2.3.41 on an i686 machine (800.63 BogoMips).
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |