Search code examples
javaandroidsocketstelnet

How to detect connection loss in a Apache SocketClient on Android?


I'm making an Android app which opens a telnet connection using Apache's TelnetClient. For this, I created a Runnable which will keep reading in processInput() forever. I check with isConnected() if the socket is still connected, and if not, I return from the runnable and call onDisconnected() on the listeners. However, this last method is never called, even when I turn of Wi-Fi.

I could check the Wi-Fi state, but that does not capture cases when the server hangs up or when the connection is lost for other reasons. How do I detect when the connection is closed?

private class ClientThread implements Runnable {
    @Override
    public void run() {
        while (true) {
            if (!client.isConnected()) {
                for (NewRecordListener listener : listeners)
                    listener.onDisconnected();

                try { client.disconnect(); } catch (IOException e) {}

                return;
            }

            try {
                processInput();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Solution

  • "I check with isConnected() if the socket is still connected"

    You cannot:

    "Returns: true if the socket successfuly connected to a server"

    does not necessarily mean it will be false as soon as the connection breaks.

    "How do I detect when the connection is closed"

    • On a non-graceful connection abort there is mostly only the chance to get an IOException while attempting to write.
    • You may want to use : AreYouThere periodically.

    Sidenote:

    I am tempted to say that this doc:

    Returns true if the client is currently connected to a server.

    is plain wrong. The docs of the Java 6 Socket.isConnected to which this method delegates to does not say that:

    Returns: true if the socket successfuly connected to a server

    Typical behavior of the Java TCP Socket implementations of isConnected is that they return true when the Socket has been successfully connected - and keep on doing so.

    See also https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#isConnected-- :

    Note: Closing a socket doesn't clear its connection state, which means this method will return true for a closed socket ... "

    That's for Java 8, though. I don't know if they just added that Note or if behavior changed, but I suspect the first.