Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing for a closed socket

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?

like image 584
Robert S. Barnes Avatar asked Mar 14 '10 11:03

Robert S. Barnes


People also ask

How do you know if a socket has been closed?

The only way to tell if the socket has been disconnected is to send data over it. set the timeout on the server side socket and then have the client check in every so often within the timeout so if you set the client to check in every 10 seconds then set the timeout to say 30 seconds on the server socket.


1 Answers

OK, so I ran some more tests and this is what I found.

I set my client up to send HTTP/1.1 Connection: close messages to the server causing the server to call close after it's last write of data. When my client finished reading data from a GET transaction it would test the socket to see if it was still open using the above method and then attempt to issue another GET.

What I found is that approximately 30% of the time my test would occur before the server's FIN arrived leading to false-positives and failed operations.

Probably the only way to make this reasonably reliable, say close to 99% would be to introduce artificial delays related to the connection latency between the last read and the attempted socket reuse - however, that would pretty much murder performance.

So, I have to conclude that while this tool is useful, it's only marginally so.

like image 128
Robert S. Barnes Avatar answered Sep 28 '22 17:09

Robert S. Barnes