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