此问题是间歇性的,每30小时运行一次,每隔几个小时发生一次,并执行以下网络通信:
当客户端尝试开始侦听同一端口时,会在客户端上发生JVM_Bind错误,即使它仅在原始套接字关闭后尝试执行此操作。在套接字关闭和打开新套接字之间添加100毫秒的轻微延迟可以防止JVM_Bind错误。
我可以使用哪些工具来调试此方案?运行连续的netstat没有显示任何干扰端口的事情。
即使在同一个端口上启动一个新套接字是一个坏主意,为什么会间歇性地发生这个错误呢?
编辑:一些其他信息。服务器从服务器上的临时端口连接回客户端。客户端的旧套接字将直接进入CLOSED并且应该能够重新打开。难道不可能是OS,JVM或硬件上发生的事情吗?
答案 0 :(得分:1)
来自Docs
当TCP连接关闭时,连接可能会在连接关闭后的一段时间内保持超时状态(通常称为TIME_WAIT状态或2MSL等待状态)。对于使用众所周知的套接字地址或端口的应用程序,如果在涉及套接字地址或端口的超时状态中存在连接,则可能无法将套接字绑定到所需的SocketAddress。
为什么它会进入这种状态详细here。
现在每次断开套接字时都不会发生这种情况,这就是为什么问题可能是断断续续的原因。
在使用bind(SocketAddress)绑定套接字之前启用SO_REUSEADDR允许套接字绑定,即使先前的连接处于超时状态。
socket.setReuseAddress(true);
答案 1 :(得分:1)
在搞乱这个问题后,我们最终运行了Wireshark和Procmon来监控TCP连接和数据包。 Procmon是用于调试Windows上的问题的非常好的工具,可以配置为显示何时创建和删除TCP连接。 Wireshark显示跨越线路的实际分组数据。此输出显示事件正在进行,因为它们应该在JVM_Bind错误发生时。日志在工作时和失败时之间没有实质性差异。
这指责了系统。我考虑了系统设置,然后把注意力转向了驱动程序问题的可能性。更新了网络适配器驱动程序,问题已经消失。
故事的道德是使用Wireshark和Procmon调试网络问题,它将此问题转化为可分析的问题。