套接字 - 已在空闲套接字上使用的地址 - 但仅限于未处于调试模式时

时间:2014-11-26 18:29:25

标签: java exception serversocket debug-mode

我写了一个正在侦听套接字的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的机器上,不会出现问题。

0 个答案:

没有答案