Connector Disconnect Detection Using TCP KeepAlive

I am developing a server that hosts third-party devices using the TCP / IP protocol, and there is a sudden drop in connection (devices connect via a cellular network). I need to find a way to detect a trip without writing data to the device.

I examined the use of TCP keepalive functionality, but Java does not seem to be able to adjust the synchronization of keepalive operations.

Is there any suggested method for 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 is welcome.

+6
source share
5 answers

You cannot go far beyond the built-in keep-alives of the TCP stack. This is because the save interval cannot be configured by your application, it is set by the OS, and the default values โ€‹โ€‹are quite high (hours). This does not apply to Java.

If you need a timeout in a reasonable amount of time, you must implement some kind of protocol in the protocol that will be used. Most of the high-level protocols I've seen have some kind of NOP functionality where you post "Are you there?". and the other side sends the answer โ€œYes, I'm hereโ€, without doing anything else.

+6
source

Set the read timeout with setSoTimeout(), to a reasonable value, say, double the expected response time and catch the received SocketTimeoutException.

NB there is no such thing as โ€œJava TCP KeepAliveโ€.

0
source

When you call setKeepalive () on a socket, system parameters (which can be rebuilt) are used. (Tested on Debian 8 with openjdk7.)

Since I needed exactly the same functionality, I wrote a small library called libdontdie , which can be preloaded and works with Java.

0
source

For a detailed discussion of TCP Keep-Alives, see my answer here .

But basically TCP Keep-Alives is probably the best method for detecting an obsolete connection. The main problem is that the default values โ€‹โ€‹for the OS are set 2 hours before the connection is checked for another 11 minutes of Keep-Alive packets before the connection is truly deleted.

Do not write your own Keep Alive protocol at the application level when TCP has already built it. All you have to do is set the TCP timeout to be more reasonable than 2-3 minutes.

Unfortunately, since TCP timeouts are managed at the OS level and not from the JVM, it is difficult (but not impossible) to configure TCP timeouts from your code based on each socket.

0
source

The author of this library is here :-)

As mentioned earlier, if you do not rely on hard-to-reach functions implemented directly in the TCP protocol (keep-alives), you are unlikely to be able to detect failures without actually sending data over the connection.

The linked library encapsulates traditional Java sockets, adding easily customizable periodic connection checks and ACKing. (This will remain invisible to the programmer). As soon as a malfunction is detected, all entered observers will be notified. (Depending on your configuration, which may be close to real time).

The surface is that lib is fairly easy to use (and, at least in my own projects, it works quite reliably).

The disadvantage is that the application layer is not intended to test connectivity. Thus, it is basically that lib uses things in ways that they are probably not intended to.

Side Note: You mentioned that your customers are cellular. Although the linked library will run on android, you can take a look at Push Notification Services instead of fixing connection problems yourself. This can improve, for example, battery consumption.

0
source

Source: https://habr.com/ru/post/957412/


All Articles