1

I have a Java application that connects to a service using a socket. I always expect to receive something from that socket, and if it disconnects I need to reconnect. Reconnect works fine when I close/open socket from remote application side in normal way. But when the remote application is killed, my Java application does not detect that. I run the thread with:

if (socket.isConnected()) { /* code */ }

This function does not detect when the socket is killed. Why? How to detect that remote socket is killed?

Note: I must use java 1.4

UPD

I do reading from socket input stream acording loggic:

 if (in.available()) {...}

This not detects socket is disconnected. Should I use in.read() even if no data available to detect closed socket?

vico
  • 17,051
  • 45
  • 159
  • 315
  • *Closing a socket doesn't clear its connection state, which means this method will return true for a closed socket (see `isClosed()`) if it was successfuly connected prior to being closed.* - from [Socket#isConnected Documentation](https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#isConnected%28%29) – Jonny Henly Apr 18 '16 at 08:41

2 Answers2

5

The various isXXX() methods of Socket don't track the actual state, but what has been done to the socket. For example isConnected() will return true even after a socket has been closed, if it has been connected at some point.

The only way to detect if a Socket is still valid is to try to use it, i.e. read or write to it. If an exception is thrown, you need to clean up and reconnect.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • Read is simpler than send something. Message body UPD contains my read from socket experience. How I can read something if nothing is available on socket? – vico Apr 18 '16 at 12:31
  • 1
    I didn't specify that you should use either one. I just said that the **only** way is to **use** the socket, i.e. read **or** write from/to it. – Kayaman Apr 18 '16 at 12:37
2

This function does not detect when the socket is killed. Why?

These functions only tell you the current state of the Socket object: they don't actively test the line. isConnected() means 'have I ever connected?'.

How to detect that remote socket is killed?

You need to read a message from the connection with an appropriate timeout. If the connection is closed or lost you eventually get an IOException, or a timeout will be reached.

BTW To save error messages, I suggest you send a message indicating a graceful disconnect before closing. This way graceful disconnects can be treated differently to connection failures in term of logging.

user207421
  • 305,947
  • 44
  • 307
  • 483
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • how to send graceful disconnect? Is it standard socket function? – vico Apr 18 '16 at 12:32
  • @vico you need to add your own protocol to send messages over TCP. You can add a message which is a poison pill which causes the other end to close the connection gracefully. This way the other end knows if the close was deliberate (and possibly handled silently) or unexpectedly. – Peter Lawrey Apr 18 '16 at 16:57
  • @vico Close the socket, or shut it down for output. – user207421 Oct 31 '19 at 04:39