Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting Socket Disconnect Using TCP KeepAlive

I'm developing a server that hosts 3rd party devices over TCP/IP and have been experiencing sudden connection drops (the devices are connecting via cellular). I need to find a way to detect a disconnect without having to write data to the device itself.

I've looked at using the TCP keepalive functionality but Java doesn't appear to allow any adjustment of the timing of the keepalive operations.

Is there any suggested method for doing this?

My simplified socket code is as follows:

public class Test2Socket {
    public static void main(String[] args) {
        try {
            ServerSocket skt = new ServerSocket(1111);

            Socket clientSocket = skt.accept();

            clientSocket.setKeepAlive(true);

            System.out.println("Connected..");

            BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            String inputLine;

            while((inputLine = input.readLine()) != null)
            {
                System.out.println(inputLine);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Any feedback would be greatly appreciated.

like image 934
PeteMitchell Avatar asked Nov 05 '13 10:11

PeteMitchell


People also ask

How does TCP detect disconnect?

In TCP there is only one way to detect an orderly disconnect, and that is by getting zero as a return value from read()/recv()/recvXXX() when reading. There is also only one reliable way to detect a broken connection: by writing to it.

How does TCP keepalive work?

The TCP Keepalive Timer feature provides a mechanism to identify dead connections. When a TCP connection on a routing device is idle for too long, the device sends a TCP keepalive packet to the peer with only the Acknowledgment (ACK) flag turned on.

What is a keep-alive probe?

Answer. TCP keepalive probes provide a method to remove dead sockets and notify applications of unresponsive peers across a TCP connection. While terminating or killing a program causes a FIN packet or possibly a RST packet to be sent, a system crash, hard reboot or network outage does not generate any packets.

How long does a socket connection stay open when idle?

Idle ESTAB is forever These sockets have no running timer by default - they will remain in that state forever, even if the communication is broken. The TCP stack will notice problems only when one side attempts to send something.


1 Answers

You will not get far with the built-in keep-alives of the TCP stack. That's because the keep-alive interval cannot be tuned by your application, it is set by the OS, and the defaults are rather high (hours). This is not specific to Java.

If you need to time out in a reasonable time, you have to implement some kind of keep alive in the protocol to be used. Most of the high-level protocols I have seen have some kind of NOP functionality, where you send an "Are you there?" message and the other party sends a "Yes, I'm here" reply without doing anything else.

like image 125
Laszlo Valko Avatar answered Oct 07 '22 11:10

Laszlo Valko