我在使用 Java 套接字 API 时遇到了一些问题。我正在尝试显示当前连接到我的游戏的玩家数量。很容易确定玩家何时连接。但是,使用套接字 API 确定玩家何时断开连接似乎不必要地困难。
在远程断开连接的套接字上调用 isConnected()
似乎总是返回 true
。同样,在远程关闭的套接字上调用 isClosed()
似乎总是返回 false
。我读过要实际确定套接字是否已关闭,必须将数据写入输出流并且必须捕获异常。这似乎是处理这种情况的一种非常不干净的方法。我们将不得不不断地通过网络发送垃圾消息,以了解套接字何时关闭。
还有其他解决办法吗?
原文由 Dan Brouwer 发布,翻译遵循 CC BY-SA 4.0 许可协议
没有 TCP API 可以告诉您连接的当前状态。
isConnected()
和isClosed()
告诉你 套接字 的当前状态。不是一回事。isConnected()
告诉 你 是否连接 _了这个插座_。你有,所以它返回真。isClosed()
告诉 你 是否关闭 了这个套接字。 直到你有,它返回 false。如果对 等 方已经以有序的方式关闭了 连接
read()
返回-1readLine()
返回null
readXXX()
抛出EOFException
对于任何其他 XXX。写入将抛出
IOException
:“对等方重置连接”,最终会受到缓冲延迟的影响。如果连接因任何其他原因断开,写入将抛出
IOException
,最终,如上所述,读取可能会做同样的事情。如果对等方仍处于连接状态但未使用该连接,则可以使用读取超时。
与您在其他地方可能读到的内容相反,
ClosedChannelException
没有告诉您这个。 [也没有SocketException: socket closed.
] 它只是告诉你 你 关闭了 频道, 然后继续使用它。换句话说,您的编程错误。它并不表示已关闭 连接。作为在 Windows XP 上使用 Java 7 进行的一些实验的结果,如果:
OP_READ
select()
返回大于零的值SelectionKey
已经无效(key.isValid() == false
)这意味着对等方已重置连接。然而,这可能是 JRE 版本或平台特有的。