1

此问题是间歇性的,在每 30 秒运行一次并执行以下网络通信的进程上每隔几个小时就会发生一次:

  • 远程机器上有一个服务器正在监听
  • 客户端连接到这台机器并告诉服务器连接回它
  • 服务器关闭套接字并重新连接到客户端
  • 当客户端关闭套接字时,客户端立即开始在同一端口上侦听

JVM_Bind 错误发生在客户端尝试开始侦听同一端口时,即使它仅在原始套接字关闭后才尝试执行此操作。在套接字关闭和打开新套接字之间添加 100 毫秒的轻微延迟可防止 JVM_Bind 错误。

我可以使用哪些工具来调试此场景?连续运行 netstat 没有显示任何干扰端口的内容。

即使在同一个端口上启动一个新的套接字监听是一种坏主意,为什么这个错误会间歇性地发生?

编辑:一些附加信息。服务器从服务器上的临时端口连接回客户端。客户端的旧套接字将直接进入 CLOSED 并且应该能够重新打开。可能的原因不会是操作系统、JVM 或硬件上发生的事情吗?

4

2 回答 2

1

文档

当 TCP 连接关闭时,连接可能会在连接关闭后的一段时间内保持超时状态(通常称为 TIME_WAIT 状态或 2MSL 等待状态)。对于使用众所周知的套接字地址或端口的应用程序,如果存在涉及套接字地址或端口的处于超时状态的连接,则可能无法将套接字绑定到所需的 SocketAddress。

为什么会进入这种状态,这里详述。

这是它进入TIME_WAIT状态的方式

现在,每次断开套接字时都不会发生这种情况,这就是为什么问题可能是间歇性的。

在使用 bind(SocketAddress) 绑定套接字之前启用 SO_REUSEADDR 允许绑定套接字,即使先前的连接处于超时状态。

socket.setReuseAddress(true);
于 2012-07-06T13:37:11.023 回答
1

在解决了这个问题之后,我们最终运行了 Wireshark 和 Procmon 来监控 TCP 连接和数据包。Procmon 是一个非常好的调试 Windows 问题的工具,可以配置为显示 TCP 连接的创建和删除时间。Wireshark 显示通过线路的实际数据包数据。此输出表明,当 JVM_Bind 错误发生时,事情正在按应有的方式进行。工作时和失败时的日志没有实质性差异。

这将责任归咎于系统。我考虑了系统设置,然后将注意力转向驱动程序问题的可能性。更新了网络适配器驱动程序,问题就消失了。

故事的寓意是用 Wireshark 和 Procmon 调试网络问题,它把这个问题变成了一个可分析的问题。

于 2012-11-05T20:36:40.563 回答