检查ClientSocket在Java中是否已断开连接

基本上,我有一个服务器循环,用于管理与一个单独客户端的连接。在循环的某一时刻,如果存在ClientSocket,它将尝试读取以检查客户端是否仍然连接:

if (bufferedReader.read()==-1 ) {

logger.info("CONNECTION TERMINATED!");

clientSocket.close();

setUpSocket(); //sets up the server to reconnect to the client

}else{

sendHeartBeat(); //Send a heartbeat to the client

}

问题是,一旦创建了套接字,应用程序将挂起读取,我假设正在等待永远不会到来的数据,因为客户端永远不会发送到服务器。在此之前还可以,因为正确处理了断开连接(客户端断开连接后读取将最终失败),并且循环将尝试重新建立连接。但是,我现在添加了上面的sendHeartBeat()方法,该方法会定期让客户端知道服务器仍在运行。如果读取保留线程,则心跳永远不会发生!

因此,我假设我正在测试连接是否仍不正确。作为一个快速的技巧,我可以在一个单独的线程中运行bufferedReader.read(),但是那样的话,我会遇到各种各样我实际上不想处理的并发问题。

因此,问题有几方面:1)我是否检查客户端是否正确断开连接?2)如果没有,该怎么办?3)如果我做得正确,如何使读取不被进程扣为人质?还是穿线是唯一的方法?

回答:

创建套接字时,请先设置超时:

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

}

以上是 检查ClientSocket在Java中是否已断开连接 的全部内容, 来源链接: utcz.com/qa/408887.html

回到顶部