【问题标题】:Is Socket.close() considered a clean way to end the connection?Socket.close() 是否被认为是结束连接的干净方式?
【发布时间】:2016-12-31 15:35:44
【问题描述】:

正如标题所说——如果我想关闭一个套接字连接,我只调用mySocket.close() 就足够了吗?另一边会发生什么?

或者,如果这不是要走的路,那是什么?我是否必须通过套接字发送某种“完成”消息,以便对方知道它也应该结束?

额外问题:java 文档说

关闭这个socket也会关闭这个socket的InputStream和OutputStream。

那么单独关闭套接字是否足够,或者我是否也必须显式关闭流(当然,假设我没有使用try-with-resources)?

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    关闭套接字不会在另一边做任何事情。远程主机将不知道连接已关闭。 检查连接是否关闭的唯一方法是尝试从输入/输出流读取或写入。如果-1InputStream#read()方法返回,那么第二方就知道第一方关闭了连接。抛出的IOException 也表示连接已关闭。

    通常您不需要关闭输入/输出流,因为它们在调用 Socket#close() 时已关闭。 Socket#close() 是您关闭连接唯一需要做的事情。

    但是如果你有一个包装流(例如BufferdInputStream/BufferedOutputStream),你应该明确关闭这些包装流以释放这些包装流使用的资源(例如字节缓冲区数组)。您只需要关闭顶级包装器流,因为关闭包装器会关闭包装流,这也会关闭包装流的包装流。等等……

    【讨论】:

    • 这肯定回答了我的额外问题,并感谢您。但这并没有回答我的主要问题。
    • 所以总结一下:Socket.close() 干净的方式,但我需要照顾另一边的事情(检查对于-1/Exception 并处理它,在那里也调用Socket.close())。如果我使用流包装器,我还需要先明确关闭它们。对吗?
    • 你不需要关闭另一边的套接字。但是如果你在另一边使用包装流,你也应该关闭它们,以释放使用的资源。仅当您想检查连接是否关闭时才需要检查 -1/Exception(对于您想要对套接字执行的其他操作,或关闭包装器流)。
    • 实际上从套接字读取会阻塞线程,直到它收到一些数据或发生超时。我发现要走的路是尝试写入套接字。如果客户端关闭了连接,它会立即抛出 IOException。可以正确捕获和处理此异常。
    • 我们还需要关闭DataOutputStream吗?
    【解决方案2】:

    socket.close() 是一种关闭连接的干净方法。它会导致一个 TCP FIN 数据包被发送到对等方并开始正常的 TCP 关闭序列。

    它还关闭了套接字的InputStreamOutputStream,我在文档中没有看到关于这一点的任何歧义。

    【讨论】:

    • 文档明确说明了这一点,但同时我看到了人们手动关闭流包装器的示例代码。 J. Tennié 的回答解释了为什么会这样,而这正是我在这里所缺少的。这就是我问奖金问题的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    • 2013-03-01
    • 2021-06-25
    • 1970-01-01
    相关资源
    最近更新 更多