首页 文章

客户端套接字被服务器关闭,然后客户端在同一端口上打开新套接字时出现JVM_Bind错误

提问于
浏览
1

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

  • 远程计算机上有一台服务器正在侦听

  • 客户端连接到此计算机并告诉服务器连接回它

  • server 关闭套接字并重新连接到客户端

  • 当套接字在客户端关闭时,客户端立即开始侦听同一端口

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

我可以使用哪些工具来调试此方案?运行连续的netstat没有显示任何干扰端口的事情 .

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

EDIT : 一些其他信息 . 服务器从服务器上的临时端口连接回客户端 . 客户端's old socket would go straight into CLOSED and should be able to be re-opened. Wouldn'可能是因为操作系统,JVM或硬件上发生了什么?

2 回答

  • 1

    来自Docs

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

    为什么它会进入这种状态详细here .

    This is how it enters the TIME_WAIT state

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

    Enabling SO_REUSEADDR prior to binding the socket using bind(SocketAddress) allows the socket to be bound even though a previous connection is in a timeout state.

    socket.setReuseAddress(true);
    
  • 1

    在搞乱了这个问题之后,我们最终运行了Wireshark和Procmon来监控TCP连接和数据包 . Procmon是用于调试Windows上的问题的非常好的工具,可以配置为显示何时创建和删除TCP连接 . Wireshark显示跨越线路的实际分组数据 . 此输出显示事件正在进行,因为它们应该在JVM_Bind错误发生时 . 日志与失败之间的日志没有任何实质性差异 .

    这指责了系统 . 我考虑了系统设置,然后把注意力转向了驱动程序问题的可能性 . 更新了网络适配器驱动程序,问题已经消失 .

    故事的道德是用Wireshark和Procmon来调试网络问题,它将这个问题变成了一个可分析的问题 .

相关问题