Getting Disconnection Notification Using Tcp Keep-Alive on Write Blocked Socket

Getting disconnection notification using TCP Keep-Alive on write blocked socket

If you pull the network connection before all the data is transmitted, then the connection is not idle and thus in some implementations the keepalive timer does not start. (Keep in mind that keepalive is NOT part of the TCP specification and as a result it is implemented inconsistently if at all.) In general, because of the combination of exponential backoff and large number of retries (tcp_retries2 defaults to 15) it can take up to 30 minutes for transmission retries to time out before the keepalive timer starts.

The workaround, if there is one, depends on the particular TCP implementation you are using. Some newer versions of Linux (kernel version 2.6.37 released 4 January, 2011) implement TCP_USER_TIMEOUT. More info here.

The usual recommendation is to implement communication timeouts at the application level rather than use TCP-based keepalive anyway. See, for example, HTTP Keep-Alive.

Is there a way to use TCP keepalive as an event?

Is there a way to use TCP keepalive as an event?

No. TCP keepalives are not seen by the application.

lifetime of a physically disconnected tcp socket without keepalive

On the send side, it would fill up the send buffer since it cannot send the data to the client. The outgoing packets (as much allowed by the receive window and available space in the send buffer would simply sit in the send buffer and TCP would end up retransmitting them.

URL: http://linux.die.net/man/2/send

If the socket is blocking, then the send() call would simply block and the application would end up waiting for this call. If the socket is non-blocking, then the send() call would return -1 and set the errno to EAGAIN or EWOULDBLOCK.

Setting SO_KEEPALIVE is certainly the main option for such sockets. In addition, you could also play around with tcp_retries1 and tcp_retries2 values mentioned in /proc/sys/net/ipv4/. When the sender kills the connection due to tcp_retries2 limit reached, the next blocking call would return a value of -1 and the errno would be set to ETIMEDOUT. Please note that these options are applied globally to all sockets on the box -- so we should use it with care.

How can I get notified of client disconnects?

It is a general TCP problem that the machine on one end of a connection can go away without any notification to the machine on the other end. Machines are not supposed to do that, but it isn't always under their control. The usual way for one end to avoid waiting forever for data in such a case, and / or to avoid being loaded down with dead connections, is to employ a timeout.

The general problem is bigger than you described, but you should be able to solve the particular part you asked about by invoking setSoTimeout() on the socket some time before you try to read from it. The socket will then throw an exception if your read attempt blocks for longer than the time you specify. This setting persists for the lifetime of the socket (or until you set a different value), so you can apply it immediately after accepting the connection if you wish.

Be aware, however, that a sufficiently long period of simple client inactivity can also cause a timeout.

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

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.

TcpClient/NetworkStream not detecting disconnection

is to pull out the network cable on the wifi box

That's a good test. If you do that the remote party is not notified. How could it possibly find out? It can't.

when I try, the write passes as if nothing is wrong

Writes can (and are) buffered. They eventually enter a block hole... No reply comes back. The only way to detect this is a timeout.

So am I doing something wrong here?

You have tried a lot of things but fundamentally you cannot find out about disconnects if no reply comes back telling you that. Use a timeout.

TCP Dead link detection

OMG what a noob error :) i found it

Diff:

17c17
< retval = setsockopt(socket_fd, IPPROTO_TCP, SO_KEEPALIVE,
---
> retval = setsockopt(socket_fd, SOL_SOCKET, SO_KEEPALIVE,


Related Topics



Leave a reply



Submit