我在使用 Java 套接字 API 时遇到了一些问题。我正在尝试显示当前连接到我的游戏的玩家数量。很容易确定玩家何时连接。但是,使用套接字 API 确定玩家何时断开连接似乎是不必要的困难。
在远程断开的套接字上调用 isConnected()
似乎总是返回 true
。同样,在远程关闭的套接字上调用 isClosed()
似乎总是返回 false
。我已经读过,要实际确定套接字是否已关闭,必须将数据写入输出流并且必须捕获异常。这似乎是处理这种情况的一种非常不干净的方式。我们只需要不断地通过网络发送垃圾消息,才能知道套接字何时关闭。
还有其他解决办法吗?
最佳答案
没有可以告诉您当前连接状态的 TCP API。 isConnected()
和 isClosed()
告诉您当前套接字的状态。不是一回事。
isConnected()
告诉你你是否连接了这个socket。你有,所以它返回 true。isClosed()
告诉你你是否关闭了这个socket。在你关闭之前,它返回false。如果peer已经有序地关闭了连接
read()
返回 -1readLine()
返回null
readXXX()
为任何其他 XXX 抛出EOFException
。写入将抛出
IOException
: 'connection reset by peer',最终会受到缓冲延迟。
如果连接因任何其他原因断开,则写入操作最终会抛出
<IOException
,如上所述,而读取操作可能会做同样的事情。如果对端仍然连接但未使用连接,则可以使用读取超时。
与您可能在其他地方看到的相反,
ClosedChannelException
并没有告诉您这一点。 [SocketException: socket closed.
] 它也只告诉你你关闭了 channel ,然后继续使用它。换句话说,您的编程错误。它并不表示已关闭连接。在 Windows XP 上对 Java 7 进行了一些实验,结果表明:
- 您正在选择
OP_READ
select()
返回大于零的值- 关联的
SelectionKey
已经无效(key.isValid() == false
)
这意味着对等方已重置连接。但是,这可能是 JRE 版本或平台所特有的。
- 您正在选择
关于Java 套接字 API : How to tell if a connection has been closed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10240694/