I'm trying to test for a closed socket that has been gracefully closed by the peer without incurring the latency hit of a double send to induce a SIGPIPE
.
One of the assumptions here is that the socket if closed was gracefully closed by the peer immediately after it's last write / send. Actual errors like a premature close are dealt with else where in the code.
If the socket is still open, there will be 0 or more bytes data which I don't actually want to pull out of the socket buffer yet.
I was thinking that I could call int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK);
to determine if the socket is still connected. If it's connected but there's no data in the buffer I'll get a return of -1
with errno == EAGAIN
and return the sockfd for reuse. If it's been gracefully closed by the peer I'll get ret == 0
and open a new connection.
I've tested this and it seems to work. However, I suspect there is a small window between when I recv the last bit of my data and when the peer FIN
arrives in which I could get a false-positive EAGAIN
from my test recv
.
Is this going to bite me, or is there a better way of doing this?