0

I'm connecting a TCP socket and opening a buffered reader for I/O on that socket in its own thread, then reading data using readLine on the buffered reader:

try {
  socket = new Socket(targetHost, targetPort);
  ou = new PrintWriter(socket.getOutputStream(), true);
  in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

  while (true) {
    message = in.readLine();
    ...
    process the data
    ...
  }
} catch (Exception e) {
  e.printStackTrace();
  return;
}

This works fine as long as the connection is there. But when the other end of the TCP connection unexpectedly goes away, in about 75% of all cases, this thread never realises the other side has gone away, and any attempts to read from the buffered reader will simply yield a "null" string, but no exception is thrown, and I'm unable to shut the thread down because it doesn't know the other side has gone away. In about 25% of the cases, the thread is terminated (also without generating an exception) but that yields the desired outcome, I just need the thread to go away when the TCP connection drops.

I tried using this to figure out if the connection is alive:

boolean connected = socket.isConnected() && !socket.isClosed();

but that doesn't work, always returns true when the other side has gone away and the thread keeps on chomping.

Any ideas anyone?

Balthasar
  • 1,227
  • 2
  • 13
  • 24
  • define "gone away". the way TCP connections work, if the other side closed the connection, you should see the exception. However, if the other side simply became unreachable (for example a cable was pulled, or the server was turned off, there will be a long timeout before TCP figures out something is wrong. – Roberto Attias Dec 27 '16 at 07:43
  • Gone away means the program at the other end decided to quit. Not crash, but quit. That means it closes the TCP connection. There should be an event detectable at the client end when a connection is dropped, no? – Balthasar Dec 27 '16 at 07:51
  • 1
    Where does it say it should throw an exception? And why aren't you ceasing to read when `readLine()` returns null, which means ' end of stream', as per the Javadoc? That's the 'event' you are looking for. – user207421 Dec 27 '16 at 08:02
  • The *other end* gong away does not constitute a 'closed socket'. It constitutes a dropped connection. – user207421 Jan 07 '17 at 23:36

1 Answers1

2

The point is basically: "works as designed".

The reader returning null actually means: "no more data; I am done here".

See the javadoc:

Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

In other words: the socket going closed is seen as "normal" operation here; thus there is no exception. In other words: you have to change your code to check if the result to readLine() returns null; and if so, you know what the socket is gone.

GhostCat
  • 137,827
  • 25
  • 176
  • 248