Java server socket doesn't reuse address

java, serversocket, time-wait

Solution

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

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

Problem

I am using a server socket in linux and I need to close it and reopen before the time_wait TCP status expires. I set the reuse address option of the server socket before the binding but it still throws a BindException. I also tried this http://meteatamel.wordpress.com/2010/12/01/socket-reuseaddress-property-and-linux/ but it still doesn't work. 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. 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'); } ```

Original source