Java套接字API:如何判断连接是否已关闭?

Java套接字API:如何判断连接是否已关闭?,java,sockets,networking,client-server,Java,Sockets,Networking,Client Server,我在Java套接字API方面遇到了一些问题。我正在尝试显示当前连接到我的游戏的玩家数量。很容易确定玩家何时连接。然而,似乎很难确定播放器何时使用套接字API断开了连接 在远程断开连接的套接字上调用isConnected()似乎总是返回true。类似地,在远程关闭的套接字上调用isClosed()似乎总是返回false。我已经读到,要真正确定套接字是否已关闭,必须将数据写入输出流,并且必须捕获异常。这似乎是处理这种情况的一种非常不干净的方式。我们只需要不断地通过网络发送垃圾消息,就可以知道套接字何

我在Java套接字API方面遇到了一些问题。我正在尝试显示当前连接到我的游戏的玩家数量。很容易确定玩家何时连接。然而,似乎很难确定播放器何时使用套接字API断开了连接

在远程断开连接的套接字上调用
isConnected()
似乎总是返回
true
。类似地,在远程关闭的套接字上调用
isClosed()
似乎总是返回
false
。我已经读到,要真正确定套接字是否已关闭,必须将数据写入输出流,并且必须捕获异常。这似乎是处理这种情况的一种非常不干净的方式。我们只需要不断地通过网络发送垃圾消息,就可以知道套接字何时关闭


还有其他解决方案吗?

在各种消息传递协议中,通常都会保持彼此心跳(保持发送ping数据包)。数据包不需要很大。探测机制将允许您检测断开连接的客户端,甚至在TCP发现之前(TCP超时要高得多)发送探测并等待5秒以获得答复,如果您没有看到后续2-3次探测的答复,则表明您的播放机已断开连接


另外,

在各种消息传递协议中,保持彼此心跳(保持发送ping数据包)是普遍做法。数据包不需要很大。探测机制将允许您检测断开连接的客户端,甚至在TCP发现之前(TCP超时要高得多)发送探测并等待5秒以获得答复,如果您没有看到后续2-3次探测的答复,则表明您的播放机已断开连接


另外,

我看到了刚才发布的另一个答案,但我认为您与玩游戏的客户是互动的,因此我可能会提出另一种方法(而BufferedReader在某些情况下绝对有效)

如果你想。。。您可以将“注册”责任委托给客户。也就是说,您将拥有一个连接用户的集合,每个用户在收到的最后一条消息上都有一个时间戳。。。如果客户超时,您将强制重新注册该客户,但这将导致下面的报价和想法

我读过这篇文章,实际上是为了确定套接字是否 必须将已关闭的数据写入输出流和异常 必须被抓住。这似乎是一种非常不干净的处理方式 情况

如果您的Java代码没有关闭/断开套接字,那么如何通知您远程主机关闭了您的连接?最终,您的try/catch所做的事情与轮询器在实际套接字上侦听事件所做的事情大致相同。考虑以下事项:

  • 您的本地系统可以在不通知您的情况下关闭您的套接字。。。这只是套接字的实现(即,它不会轮询硬件/驱动程序/固件/任何状态更改)
  • 新套接字(代理服务器p)。。。有多个参与方(实际上是6个端点)可能正在关闭您的连接

我认为抽象语言的一个特点是你是从细节中抽象出来的。考虑一下在C#(try/finally)中为SQLConnections或其他任何东西使用关键字。。。这只是做生意的成本。。。我认为try/catch/finally是Socket使用的公认且必要的模式。

我看到了刚才发布的另一个答案,但我认为您与玩游戏的客户是互动的,因此我可能会提出另一种方法(而BufferedReader在某些情况下绝对有效)

如果你想。。。您可以将“注册”责任委托给客户。也就是说,您将拥有一个连接用户的集合,每个用户在收到的最后一条消息上都有一个时间戳。。。如果客户超时,您将强制重新注册该客户,但这将导致下面的报价和想法

我读过这篇文章,实际上是为了确定套接字是否 必须将已关闭的数据写入输出流和异常 必须被抓住。这似乎是一种非常不干净的处理方式 情况

如果您的Java代码没有关闭/断开套接字,那么如何通知您远程主机关闭了您的连接?最终,您的try/catch所做的事情与轮询器在实际套接字上侦听事件所做的事情大致相同。考虑以下事项:

  • 您的本地系统可以在不通知您的情况下关闭您的套接字。。。这只是套接字的实现(即,它不会轮询硬件/驱动程序/固件/任何状态更改)
  • 新套接字(代理服务器p)。。。有多个参与方(实际上是6个端点)可能正在关闭您的连接

我认为抽象语言的一个特点是你是从细节中抽象出来的。考虑一下在C#(try/finally)中为SQLConnections或其他任何东西使用关键字。。。这只是做生意的成本。。。我认为try/catch/finally是套接字使用的公认且必要的模式。

我认为这是tcp连接的本质,在该标准中,在传输过程中大约需要6分钟的静默时间,我们才能得出断开连接的结论!
所以我认为你找不到解决这个问题的精确方法。也许更好的方法是编写一些方便的代码来猜测服务器何时应该假定用户连接已关闭。

我认为这是tcp连接的本质,在该标准中,在传输过程中大约需要6分钟的静默时间,然后我们才能得出断开连接的结论! 所以我认为你找不到解决这个问题的精确方法。也许更好的方法是编写一些方便的代码来猜测服务器何时应该假定用户连接已关闭。

sockAdr = new InetSocketAddress(SERVER_HOSTNAME, SERVER_PORT); socket = new Socket(); timeout = 5000; socket.connect(sockAdr, timeout); reader = new BufferedReader(new InputStreamReader(socket.getInputStream()); while ((data = reader.readLine())!=null) log.e(TAG, "received -> " + data); log.e(TAG, "Socket closed !");

 while(true) {
        if((receiveMessage = receiveRead.readLine()) != null ) {  

        System.out.println("first message same :"+receiveMessage);
        System.out.println(receiveMessage);      

        }
        else if(receiveRead.readLine()==null)
        {

        System.out.println("Client has disconected: "+sock.isClosed()); 
        System.exit(1);
         }    }