Search code examples
csocketstcp

Does half shutdown of a socket cause epoll to stop receiving events?


Let's say I have a client and server model communicating with each other, and epoll is set on the server-side to wake on EPOLLIN and EPOLLOUT. From my understanding, changes in the availability of the client's read/write end of the socket will trigger an epoll event to fire in the server. Say I do a half-shutdown on the client, so I shutdown the client's write end. Then, as expected, I receive an EPOLLIN event on the server side. However, now, let's say I close the read end of the socket. epoll_wait is not waking upon this happening. What I was thinking may be happening is that once the write end of the client gets closed, it can't send any notification to the server that it's closing the reading end. On the other hand, I thought that having EPOLLOUT would tell me any changes with the status of the client's read end / server's write end, but it's not.

I know that I could check for a failed write / SIGPIPE to see if the client has shutdown their read end, but I'm more curious if this is expected behavior or an issue with my code, and if it's expected, why it's this way?


Solution

  • The server will not receive a notification when the client closes its "read end".

    Instead, when the server has detected the client has closed its "write end", the server should then decide when it is finished writing data, and then close its own "write end". That will completely close the TCP connection.

    If you are worried that the server may prematurely close the connection before the client has read all the sent data, TCP takes care of that. The FIN packet associated with closing the "write end" is queued behind the data packets that were sent ahead of it. As long as the client is processing the data from the server with successive calls to recv, the return value of 0 will indicate that all the available data has been read.