I'm using non-blocking read/writes over a client-server TCP connection with epoll_wait
.
Problem is, I can't reliably detect 'peer closed connection' event using the EPOLLRDHUP
flag. It often happens that the flag is not set. The client uses close()
and the server, most of the time, receives, from epoll_wait
, an EPOLLIN | EPOLLRDHUP
event. Reading yields zero bytes, as expected. Sometimes, though, only EPOLLIN
comes, yielding zero bytes.
Investigation using tcpdump
shows that normal shutdown occurs as far as I can tell. I see a Flags [F.], Flags [F.], Flags [.]
sequence of events, which should correspond to FIN, FIN and ACK. SO_LINGER
is nowhere used.
I considered handling 'peer closed' on zero-byte read, however, there is the possibility that you get an EPOLLIN | EPOLLRDHUP
event with non-zero bytes available, when the peer sends & immediately closes the connection - case in which I need to base myself on the EPOLLRDHUP
. Suggestions?
EPOLLIN | EPOLLRDHUP
combination is received, which signals that that there are non-zero bytes to read and the connection was terminated, just keep reading until you get 0 bytes -- and that will signal shutdown. In other words, when you read 0, you're done -- so it suffices just to check forEPOLLIN
? – Thirtieth