Is there a way to detect that TCP socket has been closed by the remote peer, without reading from it? Is there a way to detect that TCP socket has been closed by the remote peer, without reading from it? c c

Is there a way to detect that TCP socket has been closed by the remote peer, without reading from it?


If you want to check if the socket is actually closed instead of data, you can add the MSG_PEEK flag on recv() to see if data arrived or if you get 0 or an error.

/* handle readable on A */if (B_is_not_connected) {    char c;    ssize_t x = recv(A_sock, &c, 1, MSG_PEEK);    if (x > 0) {        /* ...have data, leave it in socket buffer until B connects */    } else if (x == 0) {        /* ...handle FIN from A */    } else {        /* ...handle errors */    }}

Even if A closes after sending some data, your proxy probably wants to forward that data to B first before forwarding the FIN to B, so there is no point in knowing that A has sent FIN on the connection sooner than after having read all the data it has sent.

A TCP connection isn't considered closed until after both sides send FIN. However, if A has forcibly shutdown its endpoint, you will not know that until after you attempt to send data on it, and receive an EPIPE (assuming you have suppressed SIGPIPE).


After reading your mirror proxy application a bit more, since this is a firewall traversal application, it seems that you actually need a small control protocol to allow to you verify that these peers are actually allowed to talk to each other. If you have a control protocol, then you have many solutions available to you, but the one I would advocate would be to have one of the connections describe itself as the server, and the other connection describe itself as the client. Then, you can reset the connection the client if there is no server present to take its connection. You can let servers wait for a client connection up to some timeout. A server should not initiate any data, and if it does without a connected client, you can reset the server connection. This eliminates the issue of buffering data for a dead connection.


It appears the answer to my question is "no, not unless you are willing and able to modify your TCP stack to get access to the necessary private socket-state information".

Since I'm not able to do that, my solution was to redesign the proxy server to always read data from all clients, and throw away any data that arrives from a client whose partner hasn't connected yet. This is non-optimal, since it means that the TCP streams going through the proxy no longer have the stream-like property of reliable in-order delivery that TCP-using programs expect, but it will suffice for my purpose.


For me the solution was to poll the socket status.

On Windows 10, the following code seemed to work (but equivalent implementations seem to exist for other systems):

WSAPOLLFD polledSocket;polledSocket.fd = socketItf;polledSocket.events = POLLRDNORM | POLLWRNORM;if (WSAPoll(&polledSocket, 1, 0) > 0){    if (polledSocket.revents &= (POLLERR | POLLHUP))    {        // socket closed        return FALSE;    }}