创建套接字时,请先设置超时:
private int timeout = 10000;private int maxTimeout = 25000;clientSocket.setSoTimeout(timeout);
这样,如果读取超时,您将获得
java.net.SocketTimeoutException(必须抓住)。因此,您可以执行以下操作,假设您之前已如上所示设置了SO_TIMEOUT,并假定心跳将始终从远程系统获得响应:
volatile long lastReadTime;try { bufferedReader.read(); lastReadTime = System.currentTimeMillis();} catch (SocketTimeoutException e) { if (!isConnectionAlive()) { logger.info("ConNECTION TERMINATED!"); clientSocket.close(); setUpSocket(); //sets up the server to reconnect to the client } else { sendHeartBeat(); //Send a heartbeat to the client }}public boolean isConnectionAlive() { return System.currentTimeMillis() - lastReadTime < maxTimeout;}解决此问题的一种常见方法是将超时设置为某个数字(例如10秒),然后跟踪上一次成功从套接字读取的时间。如果您的超时时间已达到2.5倍,请放弃客户端并关闭套接字(以防万一,将FIN数据包发送到另一端)。
如果心跳信号 _不会_从远程系统获得任何响应,而只是在连接断开时最终最终更早地产生IOException的一种方式,那么您可以这样做(假设sendHeartBeat本身不会抛出IOException):
try { if (bufferedReader.read() == -1) { logger.info("ConNECTION TERMINATED with EOF!"); resetConnection(); }} catch (SocketTimeoutException e) { // This just means our read timed out ... the socket is still good sendHeartBeat(); //Send a heartbeat to the client} catch (IOException e) { logger.info("ConNECTION TERMINATED with Exception " + e.getMessage()); resetConnection();}....private void resetConnection() { clientSocket.close(); setUpSocket(); //sets up the server to reconnect to the client}


