我正在尝试轮询服务器端的套接字以检查客户端是否仍然可用。我在这里查了几个帖子,但似乎没什么用。
正如我发现没有直接的检查方式所以我试图对socket进行写操作... Java正在写入套接字(当客户端断开连接时)并且我没有得到IOException的异常
我设置了一个应该每秒执行轮询发送数据包的线程。在大约一分钟后发送到断开连接的客户端时,我得到“操作超时”的响应。
我也尝试使用套接字setSoTimeout,但它也没有按预期工作。
任何人都有任何建议如何使其发挥作用?
非常感谢你。
祝你好运, 汤姆
答案 0 :(得分:1)
为什么不接听电话,然后捕捉异常。如果您遇到损坏的管道异常或套接字超时,那么您就知道客户端不再存在。
对于这种情况,典型的方法是服务器使用setKeepAlive和getKeepAlive方法设置TCP keepalive。 http://docs.oracle.com/javase/6/docs/api/java/net/Socket.html。如果客户端消失,那么TCP keepalive将启动(因为不活动)并且它将检测到客户端已断开连接。然后,它将关闭连接。任何后续的recv()调用都将返回值-1并且错误指示相同。
答案 1 :(得分:1)
好的,我终于找到了真正有效的解决方案:
InetAddress addr = InetAddress.getByName("192.168.1.121");
addr.isReachable(1000)
像魅力一样工作,反应非常快。事实上我将它与socket一起使用,所以在我的例子中它的工作原理如下:
new Thread() {
public void run() {
while(true) {
try{
ArrayList<Socket> arr = new ArrayList(clients.values());
for(int i=0; i<Main.clients.size(); i++){
try
{
InetAddress addr = InetAddress.getByName(arr.get(i).getInetAddress().toString().replace("/", ""));
System.out.println(addr.isReachable(1000));
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
}
Thread.sleep(1000);
} catch (Exception e) { System.out.println("Shit happens: "+e); }
}}
}.start();
这不是真正优化的代码,它看起来很糟糕,但你会得到它背后的想法。整个代码用于可达主机检测线程。