Java server socket doesn't reuse address

会有一股神秘感。 提交于 2019-12-12 17:13:34

问题


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

回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/10516030/java-server-socket-doesnt-reuse-address

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!