Java 套接字 API : How to tell if a connection has been closed?

标签 java sockets networking client-server

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

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

还有其他解决办法吗?

最佳答案

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

  1. isConnected() 告诉你是否连接了这个socket。你有,所以它返回 true。

  2. isClosed() 告诉你是否关闭了这个socket。在你关闭之前,它返回false。

  3. 如果peer已经有序地关闭了连接

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

    • 写入将抛出 IOException: 'connection reset by peer',最终会受到缓冲延迟。

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

    <
  5. 如果对端仍然连接但未使用连接,则可以使用读取超时。

  6. 与您可能在其他地方看到的相反,ClosedChannelException 并没有告诉您这一点。 [SocketException: socket closed.] 它也只告诉你关闭了 channel ,然后继续使用它。换句话说,您的编程错误。它并不表示已关闭连接。

  7. 在 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/

相关文章:

HTTP 代理拒绝 Flash 套接字策略文件请求

JavaScript net.connect() - 显式设置本地端点 IP 地址

wcf - WCF 是否适合实现旧版网络服务?

java 。从包中获取 URL

java - 设置浮点精度

java - 将二维数组从行转换为 block

networking - SSH 监听器未关闭

windows - 如何以编程方式启用/禁用网络连接选项

java - 为什么我听不到127.0.0.1 :port by socket

java - 抛出异常时如何从代码开头继续执行?