此问题是间歇性的,每 30 秒运行一次并执行以下网络通信的进程每隔几个小时就会发生一次:
- 远程机器上有一个服务器正在监听
- 客户端连接到这台机器并告诉服务器连接回它
- 服务器 关闭套接字并重新连接到客户端
- 当套接字在客户端关闭时,客户端立即开始监听同一端口
JVM_Bind 错误会在客户端尝试开始监听同一端口时发生,即使它只是在原始套接字关闭后才尝试这样做。在套接字关闭和打开新套接字之间添加 100 毫秒的轻微延迟可防止 JVM_Bind 错误。
我可以使用什么工具来调试这种情况?连续运行 netstat 未显示任何干扰端口的情况。
尽管在同一端口上启动一个新的套接字监听是一种坏主意,但为什么会间歇性地出现此错误?
编辑:一些附加信息。服务器从服务器上的临时端口连接回客户端。客户端的旧套接字将直接进入 CLOSED 并且应该能够重新打开。可能的原因不会是操作系统、JVM 或硬件上发生的事情吗?
最佳答案
来自Docs
当一个TCP连接关闭时,连接可能会在连接关闭后的一段时间内保持超时状态(通常称为TIME_WAIT状态或2MSL等待状态)。对于使用众所周知的套接字地址或端口的应用程序,如果在超时状态下存在涉及套接字地址或端口的连接,则可能无法将套接字绑定(bind)到所需的 SocketAddress。
为什么会进入这个状态详解here .
现在每次断开套接字时都不会发生这种情况,这可能就是问题间歇性出现的原因。
在使用 bind(SocketAddress) 绑定(bind)套接字之前启用 SO_REUSEADDR 允许绑定(bind)套接字,即使之前的连接处于超时状态也是如此。
socket.setReuseAddress(true);
关于java - 服务器关闭客户端套接字然后客户端在同一端口上打开新套接字时出现 JVM_Bind 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11363193/