1

我编写了一个正在侦听套接字的 java 程序。

...
int port = getPort();
ServerSocket server = new ServerSocket(port);
server.accept()
...

它在 Java 1.4、5 和 6 上运行了十年左右。但在 Java 7 或 8 中,构造函数总是失败并出现以下绑定异常:

java.net.BindException: Address already in use: JVM_Bind
    at java.net.DualStackPlainSocketImpl.bind0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
    at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
    at java.net.ServerSocket.bind(ServerSocket.java:375)
    at java.net.ServerSocket.<init>(ServerSocket.java:237)
    at java.net.ServerSocket.<init>(ServerSocket.java:128)

我绝对确定,该端口是免费的,经过几次测试后,我发现了两件事:
1. 使用调试选项启动 JVM 时
-Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n
它可以工作!
2.不设置调试选项,只有第一次调用构造函数失败,第二次(同端口)总是成功!因此,以下丑陋的代码是一种解决方法:

...
int port = getPort();
try {
     server = new ServerSocket(port);
} catch(BindException e){
    server = new ServerSocket(port);
}
server.setSoTimeout(0);
server.accept()
...
<br>

但我想在任何情况下使用它:)

在我发现之后,我已经从我的 tomcat 启动文件中删除了调试选项。令人惊讶的是,Tomcat 7 在没有调试选项的情况下从 Java 7/8 开始创建 HTTP 侦听器时存在同样的问题。但是 Tomcat 7 需要 Java 7 或更高版本。
我确信 Java 7/8 和 Tomcat 7 都没有在像套接字通信这样重要的事情上出现错误。
那么我做错了什么?

我已经使用 Windows 7 Professional SP1 64 位和 JDK 7 32/64 位和 JDK 8 64 位进行了测试。

更新;
在另一台机器上,使用相同的 OS 和 jdk,问题不会发生。

4

0 回答 0