用于检查客户端是否可用的Java套接字轮询

时间:2013-09-03 17:57:56

标签: java sockets exception java-io bufferedwriter

我正在尝试轮询服务器端的套接字以检查客户端是否仍然可用。我在这里查了几个帖子,但似乎没什么用。

正如我发现没有直接的检查方式所以我试图对socket进行写操作... Java正在写入套接字(当客户端断开连接时)并且我没有得到IOException的异常

我设置了一个应该每秒执行轮询发送数据包的线程。在大约一分钟后发送到断开连接的客户端时,我得到“操作超时”的响应。

我也尝试使用套接字setSoTimeout,但它也没有按预期工作。

任何人都有任何建议如何使其发挥作用?

非常感谢你。

祝你好运, 汤姆

2 个答案:

答案 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();

这不是真正优化的代码,它看起来很糟糕,但你会得到它背后的想法。整个代码用于可达主机检测线程。