Java Detect Lost Connection

Java detect lost connection

Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.

So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.

The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.

That way you can keep track of up time and down time.

How to check if client has disconnected?

A related thread on Stackoverflow here along with the solution. Basically, the solution says that the best way to detect a client-server disconnect is to attempt to read from the socket. If the read is successfully, then the connection is active.If an exception is thrown during the read there is no connection between the client and the server. Alternatively it may happen that the socket is configured with a timeout value for the read operation to complete. In case, this timeout is exceeded a socket timeout exception will be thrown which can be considered as either the client is disconnected or the network is down.

The post also talks about using the isReachable method - refer InetAddress documentation. However, this method only tells us whether a remote host is reachable or not. This may just one of the reasons for the client to disconnect from the server. You wont be able to detect disconnection due to client crash or termination using this technique.

Server detecting a client losing connection from the socket

There are a few ways, depending on what you consider to be a "crash".

If the client process dies, the client OS will close the socket. The server can detect this by performing a read(), which will either return -1 (EOF) or raise a SocketException ("connection reset").

If the client gets into an infinite loop, the connection will remain open; the only way to detect this is by incorporating some kind of "heartbeat" into your protocol.

If the client host is rebooted or the network connection breaks, the server may not notice unless either:

  • the protocol has a "heartbeat" mechanism as above, with some kind of timeout, or
  • TCP keepalive is enabled on the socket by calling socket.setKeepAlive(true) - this instructs the OS to periodically* send a packet to check that the remote end of the connection is alive, closing the connection if not

*both Windows and Linux default to 2 hours; you can change this system-wide but not per-socket (under Java, anyway)

Checking if the internet connection is lost at runtime

I would suggest to create BaseActivity where you are initializing connectivity change listener (Observer in your case) and extend this activity with Splash, Main and other activities that you are using.

This way you are going to avoid code duplication.

Also don't forget to unregister listeners when activity is destroyed.

Also you dont need to use different threads. Here is example how to listen connectivity changes in Activity:

Register receiver first:

   @Override
public void register(Context context) {
initReceiver();
final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(receiver, intentFilter);
}

receiver

receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (isOnline()) {
hideNoConnectionError();
} else {
showNoConnectionError();
}
}
};

and isOnline()

 val isOnline: Boolean
get() {
return try {
val connectivityManager = context.getSystemService(
Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connectivityManager.activeNetworkInfo != null &&
connectivityManager.activeNetworkInfo.isConnected
} catch (exception: Exception) {
false
}
}

sorry, last method is written in Kotlin, but I think it is completely understandable



Related Topics



Leave a reply



Submit