【问题标题】:Closing a TCP connection from the server-side while letting the client know从服务器端关闭 TCP 连接,同时让客户端知道
【发布时间】:2012-02-06 02:00:48
【问题描述】:

我在服务器端的每个连接都有一个线程。当客户端不发送命令时,服务器线程处于阻塞状态:

while ((commandHeader = fromNode.readLine()) != null) {

在从 TCP 套接字获得的 OutputStream 上内部调用 readLine()。 当我从另一个线程调用 socket.close() 时,此调用会以 SocketException 唤醒,并且可以终止线程。

但是,如果客户端醒来并决定发出命令,它就会执行

stream.writeBytes("something\n");

无限期阻塞。我知道这对 TCP 来说可能很好(它只是一个半关闭。) 我可能应该在退出时向客户发送一些东西,例如“QUIT\n”;它也可以只读取 EOF。但是,如果我在发送命令之前在客户端调用 readLine() 或其他读取操作,它们会在连接未关闭时阻塞等待数据。 客户端如何在尝试写入之前检测到连接已半关闭?

【问题讨论】:

    标签: java sockets tcp


    【解决方案1】:

    当在服务器上调用 socket.close() 时,底层 TCP 连接会以典型的 FIN/FIN-ACK 序列加上 RST 数据包关闭,因此客户端会知道。当客户端随后调用 stream.writeBytes() 时,它应该会失败。如果不是,则意味着丢失了一些数据包,并且无论如何连接最终都会失败。

    【讨论】:

      【解决方案2】:

      首先,我认为您的应用程序逻辑应该避免半开 TCP 连接。您可以考虑在客户端添加计时器,以便在没有收到任何内容时再次开始轮询服务器。

      从服务器的角度来看,另一个选项是在 readLine 上设置计时器。为 readLine 创建另一个方法,在其中设置计时器,如果它超过特定时间,只需将一些默认值返回给 while 循环。

      编辑:

      您可能想read this article 特别是以下部分:IO 上阻塞的线程怎么办?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-11
        • 1970-01-01
        • 2021-08-12
        • 2023-03-23
        • 2012-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多