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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

我遇到了Java套接字API的一些问题。我试图显示当前连接到我的游戏的玩家数量。玩家连接时很容易确定。然而,使用套接字API来确定玩家何时断开连接似乎并不是很困难。

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

还有其他解决方案吗?

提问于
用户回答回答于

在各种消息传递协议中通常会保持彼此的心跳(不断发送ping数据包),数据包不需要非常大。探测机制将允许您在TCP通常计算出来之前检测断开连接的客户端(TCP超时高得多)发送探测并等待回复5秒钟,如果您没有看到对2-3的回复随后的探测器,你的播放器被断开。

用户回答回答于

没有TCP API会告诉你连接的当前状态。isConnected()isClosed()告诉你当前的套接字状态。不是一回事。

  1. isConnected()告诉你,无论已连接此套接字。你有,所以它返回true。
  2. isClosed()告诉你,无论已关闭此套接字。直到你有,它返回false。
  3. 如果对方已经以有序的方式关闭了连接
    • read() 返回-1
    • readLine() 回报 null
    • readXXX()抛出EOFException任何其他XXX。
    • 写入操作会抛出IOException:“由对等方重置连接”,最终受到缓冲延迟的影响。

  4. 如果连接由于其他原因而下降,写入操作IOException最终会像上面那样抛出,而读取操作可能会做同样的事情。
  5. 如果对等端仍然连接但未使用连接,则可以使用读取超时。
  6. 与你在其他地方看到的相反,ClosedChannelException不会告诉你这一点。[也没有SocketException: socket closed.]它只会告诉你,关闭了频道,然后继续使用它。换句话说,你的部分出现编程错误。它并不表示关闭连接。
  7. 作为Windows XP上Java 7的一些实验的结果,它也显示如果:
    • 你正在选择 OP_READ
    • select() 返回大于零的值
    • 关联SelectionKey的已经无效(key.isValid() == false

    这意味着对等方已重置连接。但是,这可能是JRE版本或平台特有的。

扫码关注云+社区