0

Currently the way I detect if a client has crashed is if an exception occurs when listening for communications. I assume this is because if the client crashes then the OS will close the socket. Will an exception still fire if if the client's internet drops out or they shutdown their PC? If not what is the best way of handling disconnections like this? Thanks.

user3313539
  • 103
  • 1
  • 2
  • 5
  • 1
    Ping client and wait for response for some time. If there is none, consider client disconnected. – svz Feb 23 '14 at 19:27
  • If you attempt to read() from a socket which is not longer there it will either a) detect the connection is gone almost immediately or b) timeout. Either way it will throw an IOException. – Peter Lawrey Feb 23 '14 at 20:06
  • 2
    @PeterLawrey However the default read timeout is infinite. You have to set it, and choosing a value can be fun. – user207421 Feb 23 '14 at 21:50
  • @EJP I thought the OS defaulted to 180 seconds if it gets no response from the other system. – Peter Lawrey Feb 23 '14 at 22:26
  • @PeterLawrey, what you're saying isn't true. Unless you're using keep-alives, the only way to detect a socket has been abruptly disconnected is [by writing to it](http://stackoverflow.com/a/6404085/372643). This is why there are timeouts and content-length indicators or message delimiters in application protocols. – Bruno May 01 '14 at 00:05
  • @Bruno You are right that to detect a failed connection you should expect a heatbeat or some data. However, if you don't send some data, TCP won't drop the connection for you. The other end has to close() it. See Warren Dew's answer. – Peter Lawrey May 01 '14 at 08:24

3 Answers3

3

TCP is designed to maintain a connection indefinitely even when no data is moving across the connection in either direction. This means that the connection will not close and you will not see an exception if the client's network or an intermediate network goes down - and in fact, if such a network goes down, and then later comes back up, even hours later, a TCP connection that was unused during that period will by default still be there and usable for further communications afterwards. You will also not get an exception if the client computer crashes or is abruptly powered off. You might get an exception if the client computer is shut down normally, since its shutdown process might include closing all connections, depending on the operating system.

If you want to disconnect when the network is lost for a certain period or when the client crashes, usually the best way to do it is by setting TCP keepalive. In Java, you can enable TCP keepalive by calling Socket.setKeepalive(true). This causes your socket to send occasional probe packets to check if the other end of the connection is still alive.

Note that the default interval between TCP keepalive checks is typically two hours, and it is typically a system wide property. If you want the interval to be less, you'll need to change the system configuration.

Warren Dew
  • 8,790
  • 3
  • 30
  • 44
0

socket timeouts are quite long and OS/implementation dependents. you need to do something active like pinging your client at regular intervals to see if it's still alive (or any over type of query that the client can answer depending on what type of communication you are using)

user3343927
  • 103
  • 1
  • 7
0

Usually there is a way to specify the timeout for every operation that you are performing cia TCP/UDP Connections. So if no response(message or ACK) is received from the client for sometime the socket would throw a SocketTimeoutException.

For example

1) socket.connect(otherAddress, timeout)

2) socket.setSoTimeout(timeout) for setting a timeout on read() operations.

Kakarot
  • 4,252
  • 2
  • 16
  • 18