Java TCP重传超时

标签 java sockets tcp operating-system

public static void main(String args[]){

    byte[] message = ...
    Socket socket = ...
    DataOutputStream dOut = new DataOutputStream(socket.getOutputStream());

    dOut.write(message);  //#1

    dOut.close();
    socket.close();
}

假设第 1 行将数据放入缓冲区等待刷新到远程机器。之后流和套接字被关闭。

我们假设在发送过程中,网络发生了一些未知的问题,我们的操作系统将重新发送缓冲区中的数据包,直到 TCP 重传超时。

我想知道如何在 Java 程序中捕获这个异常?因为上面的代码已经将数据发送到缓冲区并且可能关闭了流和套接字(并且可能退出了 Java 主体),所以将所有其他工作(与 TCP 相关,重新传输)留给了操作系统。

我的问题是,即使 Java 程序退出,TCP 重传(我们假设丢包)还会继续吗?捕获重传超时错误的最佳方法是什么?

最佳答案

即使在程序退出后,TCP 仍会继续尝试干净地关闭连接。通常建议应用程序自行执行关闭。基本上,您执行以下步骤序列:

  1. Shutdown the TCP connection in the send direction触发正常关闭序列。如果协议(protocol)禁止对方发送任何数据,你也可以关闭接收方向的连接,但是,如果你这样做并且对方发送任何数据,可能会导致对方检测到异常关闭,因为它发送的数据将丢失。

  2. 继续从连接读取数据,直到您从另一端检测到正常或异常关闭。如果一切顺利,您将在收到另一方发送的任何数据后立即检测到干净关机。

  3. 关闭句柄或删除连接的对象/引用。实际的 TCP 连接已经关闭。

关于Java TCP重传超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17637283/

相关文章:

go - 异常大量的 TCP 连接超时错误

java - 首选项文件位置

c - 关于so​​cket编程中这个strncpy函数的一个问题

sockets - fluentd aws kinesis插件没有将记录放入kinesis

Linux 识别我的 BLE?

c# - 当我从客户端向服务器发送命令时,仅当请求发送两次时,客户端才会收到响应

ios - 在 iOS 中,我们如何增加每个主机的 HTTP 连接限制?

java - 将纹理绘制到帧缓冲区会扭曲纹理

java - 任务显示的 Firebase AuthResult 无法解析符号

java - 每秒在 Fragment 中执行方法 - 第二次运行时为 NULL 值