我使用以下代码检查地址可重用性: -
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_Bind异常。 这基本上否定了使用setReuseAddress(true)OPTION。
的整个目的请帮助解决此问题。
谢谢&此致
答案 0 :(得分:0)
setReuseAddress
的javadoc说:
当TCP连接关闭时,连接可能会在连接关闭后的一段时间内保持超时状态(通常称为TIME_WAIT状态或2MSL等待状态)。对于使用众所周知的套接字地址或端口的应用程序,如果在涉及套接字地址或端口的超时状态中存在连接,则可能无法将套接字绑定到所需的SocketAddress。
在使用bind(SocketAddress)绑定套接字之前启用SO_REUSEADDR允许套接字绑定,即使先前的连接处于超时状态。
但是你所做的与这个用例不匹配。当其他一些套接字关闭时,您不会尝试绑定。实际上,当另一个套接字打开时,你正试图绑定。
让我感到困惑的是为什么你的测试实际上适用于较旧的JRE。它可能是一个JVM错误......