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

新手上路,请多包涵

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

在远程断开连接的套接字上调用 isConnected() 似乎总是返回 true 。同样,在远程关闭的套接字上调用 isClosed() 似乎总是返回 false 。我读过要实际确定套接字是否已关闭,必须将数据写入输出流并且必须捕获异常。这似乎是处理这种情况的一种非常不干净的方法。我们将不得不不断地通过网络发送垃圾消息,以了解套接字何时关闭。

还有其他解决办法吗?

原文由 Dan Brouwer 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 456
1 个回答

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

  1. isConnected() 告诉 是否连接 _了这个插座_。你有,所以它返回真。

  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 版本或平台特有的。

原文由 user207421 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题