[英]Java server socket doesn't reuse address
I am using a server socket in linux and I need to close it and reopen before the time_wait TCP status expires. 我在linux中使用服务器套接字,我需要关闭它并在time_wait TCP状态到期之前重新打开。 I set the reuse address option of the server socket before the binding but it still throws a BindException.
我在绑定之前设置了服务器套接字的重用地址选项,但它仍然抛出BindException。 I also tried this http://meteatamel.wordpress.com/2010/12/01/socket-reuseaddress-property-and-linux/ but it still doesn't work.
我也试过这个http://meteatamel.wordpress.com/2010/12/01/socket-reuseaddress-property-and-linux/,但它仍然不起作用。
To open a server socket i use: 要打开服务器套接字我使用:
ServerSocket ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(12345));
and to close: 并关闭:
ss.close();
The "Address already in use" BindException is throwed at the bind call. “已经在使用的地址”BindException在绑定调用时被抛出。
This code generates the exception: 此代码生成异常:
for (int i = 0; i < 2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
final ServerSocket ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(12345));
Socket s = ss.accept();
System.out.println((char) s.getInputStream().read());
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(500);
Socket s = new Socket("localhost", 12345);
s.getOutputStream().write('c');
}
You set reuse before binding not after you get an exception. 在获得异常之后,不在绑定之前设置重用。
ServerSocket ss = new ServerSocket(); // don't bind just yet
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(12345)); // can bind with reuse= true
This runs without error on Windows 7 and RHEL 5.x 这在Windows 7和RHEL 5.x上运行时没有错误
for (int i = 0; i < 1000; i++) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
final ServerSocket ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(12345));
Socket s = ss.accept();
System.out.println((char) s.getInputStream().read());
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(50);
Socket s = new Socket("localhost", 12345);
s.getOutputStream().write('c');
t.join();
}
You have to do that: it means extract the code so that it does not recur constantly 你必须这样做:它意味着提取代码,使其不再发生
public class....
private ServerSocket socServer;
onCreate
...
try {
socServer = new ServerSocket();
socServer.setReuseAddress(true);
socServer.bind(new InetSocketAddress(SERVER_PORT));
} catch (IOException e) {
e.printStackTrace();
}
// New thread to listen to incoming connections
new Thread(new Runnable() {
@Override
public void run() {
try
{
// Create server side client socket reference
Socket socClient = null;
// Infinite loop will listen for client requests to connect
while (true) {
// Accept the client connection and hand over communication
// to server side client socket
socClient = socServer.accept();
// For each client new instance of AsyncTask will be created
ServerAsyncTask serverAsyncTask = new ServerAsyncTask();
// Start the AsyncTask execution
// Accepted client socket object will pass as the parameter
serverAsyncTask.execute(new Socket[] {socClient});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.