Search code examples
javasocketsssldisconnected-session

Java client-side SSLSocket: How to tell if remote end has closed the connection?


I'm stuck in a conundrum here…

My client SSLSocket connects to the server (not Java) and successfully reads and writes binary data as expected. Then, at some point in time, the server disconnects the client's connection. However, the client can still call startHandshake() without throwing an exception, and I see no indication that the connection is broken except that getLocalSocketAddress() returns an IP of all 0's.

Here's what the code looks like:

SSLSocket socket = (SSLSocket)socketFactory.createSocket(host, port);
socket.setTcpNoDelay(true);
socket.setKeepAlive(true);

/* Socket happily sends/receives data */
socket.getOutputStream().write(myData);
socket.getOutputStream().flush();
socket.getInputStream().read(myBuffer);
// do something with myBuffer

Thread.sleep(20 * 1000);  // During this wait period, server disconnects the client

socket.getLocalSocketAddress();  // returns host:port as expected

socket.startHandshake();  // doing another read/write will also produce the same result

socket.getLocalSocketAddress();  // returns an IP of all zeroes: /0:0:0:0:0:0:1129:6a1f%0:51447
socket.isClosed();  // somehow, returns false!
socket.isConnected();  // somehow, returns true!

socket.getOutputStream.write(myOtherData);  // throws a SocketException: Broken pipe.

Basically, I guess my question is, is there some way of determining whether the server has broken the connection other than checking if getLocalSocketAddress() has an IP of all 0's?


Solution

    • Socket.getLocalAddress() returns all zeros if you've closed the socket, or never bound or connected it.
    • Socket.isClosed() tells you whether you've closed the socket.
    • Socket.isConnected() tells you whether you ever connected the socket.

    To test whether the peer has closed the connection:

    1. read() returns -1
    2. readLine() returns null
    3. readObject(), readInt(), readXXX() for any other XXX, throw EOFException.