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

2022-08-31 09:46:50

我在使用Java套接字API时遇到了一些问题。我正在尝试显示当前连接到我的游戏的玩家数。很容易确定玩家何时连接。但是,使用套接字 API 确定玩家何时断开连接似乎非常困难。

对已远程断开连接的套接字进行呼叫似乎总是返回 。同样,调用已远程关闭的套接字似乎总是返回 。我已经阅读了该功能,以实际确定套接字是否已关闭,必须将数据写入输出流,并且必须捕获异常。这似乎是处理这种情况的一种非常不干净的方式。我们只需要不断通过网络发送垃圾消息,就可以知道套接字何时关闭。isConnected()trueisClosed()false

还有其他解决方案吗?


答案 1

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

  1. isConnected()告诉您是否已连接此套接字。你有,所以它返回真实。

  2. isClosed()告诉您是否已关闭此套接字。直到您有,它返回 false。

  3. 如果对等方已按顺序关闭连接

    • read()返回 -1
    • readLine()返回null
    • readXXX()抛出任何其他 XXX。EOFException

    • 写入操作将抛出一个:“由对等体重置连接”,最终,受缓冲延迟的影响。IOException

  4. 如果连接因任何其他原因而断开,则写入操作最终会抛出 ,如上所述,读取操作可能会执行相同的操作。IOException

  5. 如果对等体仍处于连接状态但未使用连接,则可以使用读取超时。

  6. 与你在其他地方读到的相反,它不会告诉你这一点。[也没有]它只告诉您关闭了该通道,然后继续使用它。换句话说,就是您的编程错误。它不表示连接已关闭。ClosedChannelExceptionSocketException: socket closed.

  7. 作为在Windows XP上使用Java 7的一些实验的结果,如果出现以下情况:

    • 您正在选择OP_READ
    • select()返回大于零的值
    • 关联的已无效 (SelectionKeykey.isValid() == false)

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


答案 2

在各种消息传递协议中,通常的做法是保持彼此的检测跳动(继续发送ping数据包),数据包不需要非常大。探测机制将允许您在TCP弄清楚之前检测到断开连接的客户端(TCP超时要高得多)发送一个探测器并等待5秒的回复,如果您没有看到2-3个后续探测的回复,您的播放器将断开连接。

另外,相关问题


推荐