Divers
Divers

Reputation: 9569

How to detect FIN - tcp flag in java application?

I have long-lasting TCP connection between two computers (second not under my control). Second computer can send FIN flag at every moment, and first must close connection corrent (send FIN flag back to second computer).

How can I know that the second computer sending a FIN flag and when I must cause socket.close() method of my Java application?

Upvotes: 3

Views: 4408

Answers (3)

Hanan Oanunu
Hanan Oanunu

Reputation: 179

As explained above, the Socket's properties (isClosed, isConnected, etc) are not helpful. A proper solution would be to set a reasonable SO_TIMEOUT and read from the socket:

  • In case of connection closed by the peer, the read operation would return with '-1'
  • In case of read timeout, the read operation would throw SocketTimeoutException.

(Scala code)

val socket = new Socket("localhost", 8888)
socket.setSoTimeout(10000) /* Set reasonable read timeout */

try {
    val res = socket.getInputStream().read()

    if (res < 0) 
      ... /* Socket closed */
    else
      ... /* Socket read succeeded */

} catch {
    case _: SocketTimeoutException => ... /* Socket not closed */
    case _ => ... /* Merde */
}

Upvotes: 0

Michał Kosmulski
Michał Kosmulski

Reputation: 10020

Detecting a soft connection close by the other side (when they manage to send FIN/RST flags) is only partially possible with the old Java I/O library. You will learn of a broken connection only via a timeout, so it may be far from immediate. Your threads may hang for a long time before they realize that the party at the other end is long gone.

In order to handle it better, you need to use nio. There, such a situation will be recognized by the Selector saying there is data ready for reading but then read on the channel returning less than zero. This will allow you to learn about soft connection resets almost immediately.

On the other hand, a hard connection termination (e.g. someone cutting the wire or network being down) can only be detected via timeouts regardless of which libraries you use as it's a property of the TCP protocol itself.

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533530

Normally, you have to read the connection and when this returns -1 for EOF or an appropriate IOException, you can close the connection. Note: SocketTimeoutException doesn't mean the connection is closed.

an example.

boolean ok = false;
try {
  int b = in.read();
  ok = b >= 0;
  if (!ok)
     throw new EOFException();
} finally {
  if (!ok)
     in.close();
}

Upvotes: 3

Related Questions