How to avoid java.net.BindException: Address already in use

17,398

Solution 1

You will see that your setReuseAddress(true) is being called too late i.e. after the bind throws an exception.

You can create an unbound ServerSocket, make it reusable and then bind it, in three steps.

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

Solution 2

I had a similar problem in one of my programs, but it ended up that I was just actually running an instance of the program from my IDE - which I hadn't noticed. Always double check there isn't something running in the background.

Share:
17,398
Admin
Author by

Admin

Updated on July 25, 2022

Comments

  • Admin
    Admin almost 2 years

    The following was running for 1 hour and then closed:

    public class Mp extends JWindow implements MouseListener, MouseMotionListener {
        public static Mp j;
      private int serverPort = 0;
      private ServerSocket serverSock = null;
      private Socket sock = null; 
    
      public static void main(final String[] args) throws IOException, InterruptedException, Exception {
        j = new Mp();
        j.setVisible(true);
        j.waitForConnections();
      }
    
      public void waitForConnections() {
        while (true) {
          try {
            sock = serverSock.accept();
            System.out.println("[TCPMediaHandler]: Accepted new socket");
            TCPMediaHandler handler = new TCPMediaHandler(sock);
            handler.start();
          } catch (IOException e) {
            e.printStackTrace(System.err);
          }
        }
      }
    
      public Mp() throws IOException {
        this.serverPort = 38891;
        serverSock = new ServerSocket(serverPort);
        serverSock.setReuseAddress(true);
        //serverSock.setSoTimeout(500);
        //serverSock.setSoLinger(true, 0);
        System.out.println("[TCPMediaHandler]: Server started");      
            this.v1.setBackground(Color.BLACK);
        this.v1.addMouseListener(this);
        /* Close the window */
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
              System.exit(0); 
            }
          });
      }
    

    When I re-run the same thing it fails with a java.net.BindException:

    $ java -cp /var/tmp/dist/Mp.jar test.Mp
    Exception in thread "main" java.net.BindException: Address already in use
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:353)
        at java.net.ServerSocket.bind(ServerSocket.java:336)
        at java.net.ServerSocket.<init>(ServerSocket.java:202)
        at java.net.ServerSocket.<init>(ServerSocket.java:114)
        at test.Mp.<init>(Mp.java)
        at test.Mp.main(Mp.java)
    

    It takes about 3 to 4 minutes before it will execute successfully again. How can I make it work immediately after shutting down?

    Follow up:

    $ netstat | grep 38891
    tcp       35      0 localhost:38891         localhost:37842         CLOSE_WAIT 
    tcp        0      0 localhost:34955         localhost:38891         ESTABLISHED
    tcp       32      0 localhost:38891         localhost:37824         CLOSE_WAIT 
    tcp        0      0 localhost:38891         localhost:34955         ESTABLISHED
    
    $ lsof -w -n -i tcp:38891
    COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    xdg-scree 5254  sun   29u  IPv4 231948      0t0  TCP *:38891 (LISTEN)
    xdg-scree 5355  sun   29u  IPv4 231948      0t0  TCP *:38891 (LISTEN)
    xdg-scree 5455  sun   29u  IPv4 231948      0t0  TCP *:38891 (LISTEN)
    telnet    7058  sun    3u  IPv4 242987      0t0  TCP 127.0.0.1:34955->127.0.0.1:38891 (ESTABLISHED)
    sleep     9002  sun   29u  IPv4 231948      0t0  TCP *:38891 (LISTEN)
    sleep     9005  sun   29u  IPv4 231948      0t0  TCP *:38891 (LISTEN)
    sleep     9008  sun   29u  IPv4 231948      0t0  TCP *:38891 (LISTEN)
    
  • Admin
    Admin about 12 years
    Thank you! I have tried according to your great advise. But i still could not fix it. Please see above my edit follow up section. There are still few showing ESTABLISHED but actually i have none and even my application is terminated. But i can still do telnet localhost thatport
  • user207421
    user207421 about 12 years
    @YumYumYum the presence of a port in the CLOSE_WAIT state indicates that the application was still running when you took that netstat.
  • tobi42
    tobi42 over 7 years
    In my scenario I did not really care for the port number and could therefore use ServerSocket myServer = new ServerSocket(0); final int port = myServer.getLocalPort();
  • Vishy
    Vishy over 7 years
    @tobi42 in that case, you won't be reusing a port so it won't be a problem.