2012-05-09 14 views
1

我在linux中使用服务器套接字,我需要关闭它并在time_wait TCP状态到期之前重新打开。我在绑定之前设置了服务器套接字的重用地址选项,但仍会抛出BindException。 我也试过这http://meteatamel.wordpress.com/2010/12/01/socket-reuseaddress-property-and-linux/但它仍然无法正常工作。Java服务器套接字不重用地址

要打开服务器套接字我使用:

ServerSocket ss = new ServerSocket(); 
ss.setReuseAddress(true); 
ss.bind(new InetSocketAddress(12345)); 

,并关闭:

ss.close(); 

“地址已在使用” 的BindException在绑定呼叫倒掉。

此代码生成异常:

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'); 
    } 
+1

你可以编辑你的问题,并告诉我们你用来配置套接字的代码吗? – Gray

回答

7

您可以设置重复使用之前绑定不是你得到一个异常后。

ServerSocket ss = new ServerSocket(); // don't bind just yet 
ss.setReuseAddress(true); 
ss.bind(new InetSocketAddress(12345)); // can bind with reuse= true 

此运行没有错误在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(); 
} 
+0

我在Windows和Linux上尝试过100,000次,但没有错误。 :P –

+0

当然,但你的代码不建立TCP连接,因此在等待状态下没有连接。 (在主帖中尝试测试代码) – Daniel

+0

您不确保在开始新的之前关闭ServerSocket。 –

0

你要做的是:它意味着提取代码,以便它不复发不断

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();