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

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

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

最佳答案

您可以在绑定之前设置重用,而不是在获取异常之后。

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

07-24 09:23