I'm trying to determine if a client has closed a socket connection from netty. Is there a way to do this?
4 Answers
On a usual case where a client closes the socket via close()
and the TCP closing handshake has been finished successfully, a channelInactive()
(or channelClosed()
in 3) event will be triggered.
However, on an unusual case such as where a client machine goes offline due to power outage or unplugged LAN cable, it can take a lot of time until you discover the connection was actually down. To detect this situation, you have to send some message to the client periodically and expect to receive its response within a certain amount of time. It's like a ping - you should define a periodic ping and pong message in your protocol which practically does nothing but checking the health of the connection.
Alternatively, you can enable SO_KEEPALIVE
, but the keepalive interval of this option is usually OS-dependent and I would not recommend using it.
To help a user implement this sort of behavior relatively easily, Netty provides ReadTimeoutHandler
. Configure your pipeline so that ReadTimeoutHandler
raises an exception when there's no inbound traffic for a certain amount of time, and close the connection on the exception in your exceptionCaught()
handler method. If you are the party who is supposed to send a periodic ping message, use a timer (or IdleStateHandler
) to send it.

- 12,231
- 6
- 42
- 52
It depends on your protocol that you use ontop of netty. If you design it to support ping-like messages, you can simply send those messages. Besides that, netty is only a pretty thin wrapper around TCP.
Also see this SO post which describes isOpen()
and related. This however does not solve the keep-alive problem.

- 1
- 1

- 13,012
- 16
- 70
- 120
-
The answers in that link are mostly incorrect. There are far better answers in SO. – user207421 Jan 26 '14 at 02:59
-
@EJP Do you have a link? If you could suggest an edit, I will happily accept that! – Uli Köhler Jan 26 '14 at 02:59
-
My understanding is that tcp has keep-alive built in. Is it not possible to leverage this? – Josh Wilson Jan 26 '14 at 02:59
-
Yes, it is. TCP keep-alive is disabled by default, you would simply turn it on after establishing the connection. – Remy Lebeau Jan 26 '14 at 03:04
-
I suggest you link to [this answer](http://stackoverflow.com/questions/10240694/java-socket-api-how-to-tell-if-a-socket-has-been-closed/10241044#10241044). – user207421 Jan 26 '14 at 03:08
If you are writing a server, and netty is your client, then your server can detect a disconnect by calling select()
or equivalent to detect when the socket is readable and then call recv()
. If recv()
returns 0 then the socket was closed gracefully by the client. If recv()
returns -1 then check errno
or equivalent for the actual error (with few exceptions, most errors should be treated as an ungraceful disconnect). The thing about unexpected disconnects is that they can take a long time for the OS to detect, so you would have to either enable TCP keep-alives, or require the client to send data to the server on a regular basis. If nothing is received from the client for a period of time then just assume the client is gone and close your end of the connection. If the client wants to, it can then reconnect.

- 555,201
- 31
- 458
- 770
-
I think you've misread the question. He seems to be using Netty in the server. – user207421 Jan 26 '14 at 03:06
If you read from a connection that has been closed by the peer you will get an end-of-stream indication of some kind, depending on the API. If you write to such a connection you will get an IOException: 'connection reset'. TCP doesn't provide any other way of detecting a closed connection.
TCP keep-alive (a) is off by default and (b) only operates every two hours by default when enabled. This probably isn't what you want. If you use it and you read or write after it has detected that the connection is broken, you will get the reset error above,

- 305,947
- 44
- 307
- 483
-
On Windows 2000 and later, you can programably set the desired interval of the TCP keep-alive on a per-connection basis using `WSAIoctl(SIO_KEEPALIVE_VALS)`. – Remy Lebeau Jan 26 '14 at 03:06