views:

399

answers:

2

If I kill the Socket Server process, my Socket client process does not receive any errors, it continues to loop forever on the following code:

public void run() {
    while(readData) {
      String inputLine = null;
      try {
        while((inputLine = m_inputStream.readLine()) != null) {
          //do stuff
        }
      } catch (IOException e) {
         readData = false;
     }
  }
}

How can I detect that the socket server is gone and terminate the loop?

+4  A: 

Terminate the outer loop when the call to readLine() returns null.

No exception is thrown when the server closes the connection normally. The stream should return null to signal the end of data.

This can be done with a loop like this:

public void run() {
  try {
    while (true) {
      String line = input.readLine();
      if (line == null)
        break;
      /* Process line. */
      ...
    }
  } catch (IOException ex) {
    /* Handle the exception as desired. */
    ex.printStackTrace();
  }
}
erickson
So the stream will return null ONLY if the connection is closed?
anio
Yes - otherwise the call to read will block until there is data available to read
oxbow_lakes
The declaration of m_inputStream isn't shown, but I'm assuming it's a java.io.BufferedReader. If so, it will only return null if the socket is closed. If the server is killed abruptly, a "reset" should occur at the TCP level, and this will result in an exception being raised by the Java Socket.
erickson
Thank you. I was under the false assumption that an error would be thrown.
anio
I am using a BufferedReader. If I understand correctly, that raised exception isn't propagated as an IOException, because it is presumably caught earlier and dealt with?
anio
No, if the server "dies" (it is killed or crashes without properly closing the socket), the InputStream on the Java side will throw an exception, which propagates up through the BufferedReader. Only if the server closes the socket cleanly, the BufferedReader will return null at the end of the stream. Otherwise, calls to read from the BufferedReader will block until data is available.
erickson
A: 

Whilst the answer from erickson is correct, have you tried setting the socket read time-out properties? (e.g. sun.net.client.defaultReadTimeout). If it is possible that the server may take a long time responding, then this might be less useful as a solution to your problem but is a good idea nevertheless in many scenarios.

oxbow_lakes