地址重用不适用于新的Java Runtime Environment

我使用以下代码检查地址可重用性: –

import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; public class CheckBind { public static void main(String[] args) { Thread serverThread = new Thread(new Runnable() { @Override public void run() { try { ServerSocket server = new ServerSocket(); server.setReuseAddress(true); server.bind(new InetSocketAddress("127.0.0.1", 2000)); System.out.println("Server Listen: "+server.getLocalSocketAddress()); while(true) { Socket client = server.accept(); System.out.println(""+client.getRemoteSocketAddress()); System.out.println(""+client.getLocalSocketAddress()); } } catch (IOException e) { e.printStackTrace(); } } }); serverThread.start(); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } while(true) { Socket client = new Socket(); try { client.setReuseAddress(true); client.bind(new InetSocketAddress("127.0.0.1", 2000)); client.connect(new InetSocketAddress("127.0.0.1",4000)); System.out.println("Client Connect: "+client.getRemoteSocketAddress()); break; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } 

这在Windows 7,64bit上运行良好我使用了JRE 7U5 [1.7 Update 5] 32Bit版本。 [考虑到服务器已在127.0.0.1:4000上运行]

但是当我尝试使用更新版本的JRE时,就像我检查JRE 7U60 32位和JRE 7U72 64位一样,它提供了JVM_Bindexception。 这基本上否定了使用setReuseAddress(true)OPTION的整个目的。

请帮助解决此问题。

感谢和问候

setReuseAddress的javadoc说:

当TCP连接关闭时,连接可能在连接关闭后的一段时间内保持超时状态(通常称为TIME_WAIT状态或2MSL等待状态)。 对于使用众所周知的套接字地址或端口的应用程序,如果在涉及套接字地址或端口的超时状态中存在连接,则可能无法将套接字绑定到所需的SocketAddress。

在使用bind(SocketAddress)绑定套接字之前启用SO_REUSEADDR允许套接字绑定,即使先前的连接处于超时状态。

但是你所做的与这个用例不匹配。 当其他一些套接字关闭时,您不会尝试绑定。 实际上,当另一个套接字打开时,您正在尝试绑定。


令我困惑的是为什么你的测试实际上适用于较旧的JRE。 它可能是一个JVM错误……