Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent an app from binding to a socket that is already bound

Tags:

java

sockets

How to prevent a Java app from binding to a socket that another process is already bound to on Windows?

I have an issue where I have a Java application that is listening on port 80. The application starts fine and reports no exceptions. I couldn't figure out why I couldn't connect on port 80. Other ports worked fine. I checked netstat for other processes listening on 80 and found Skype. I didn't think that was possible, but after some research, I'm guessing Skype is listening with the SO_REUSEADDR option. In this state the accepting application is indeterminate. I would like my Java application to fail in this instance with a bind exception (or other).

It looks like I could use SO_EXCLUSIVEADDRUSE if I had access to that option via Java but I don't think that is possible. There are lots of questions and answers around SO_REUSEADDR but none that I could find that answered my question. This isn't just about Skype (I can turn off the listening part), I want my program to be more robust in this situation.

This is snippet from netstat -abn on a Windows 7 box:

    Proto  Local Address          Foreign Address        State
    TCP    0.0.0.0:80             0.0.0.0:0              LISTENING [java.exe]
    TCP    0.0.0.0:80             0.0.0.0:0              LISTENING [Skype.exe]

This is why I'm assuming that Skype is using SO_REUSEADDR

The processes don't appear to be listening on different interfaces.

Here is a snippet of the code. The port is 80:

    myServerSocket = new ServerSocket(myTcpPort);
    while (true) {
        new HTTPSession( myServerSocket.accept(), threadPool );
    }

As further information I created a sample program to minimize any side effects or mishandled messages.

    import java.net.ServerSocket;

    public class PortTest
    {
        public static void main(String[] args)
        {
            System.out.println( "Hit Ctrl-C to stop.\n" );

            try {
                ServerSocket myServerSocket = new ServerSocket(80);
                System.out.println( "Before the accept() call.");
                myServerSocket.accept();
                System.out.println( "After the accept() call." );
            }
            catch (Exception ex ) {
                System.out.println("Error listening.");
                ex.printStackTrace();
            }
         }

    }

I still don't get an exception when running this sample program (PortTest) and when Skype is running and listening on port 80. And to further test, I executed a second instance PortTest and I do see the port in use message.

    Error listening.
    java.net.BindException: Address already in use: JVM_Bind
            at java.net.DualStackPlainSocketImpl.bind0(Native Method)
            at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
            at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
            at java.net.PlainSocketImpl.bind(Unknown Source)
            at java.net.ServerSocket.bind(Unknown Source)
            at java.net.ServerSocket.<init>(Unknown Source)
            at java.net.ServerSocket.<init>(Unknown Source)
            at PortTest.main(PortTest.java:10)
like image 271
Frank Black Avatar asked May 16 '13 15:05

Frank Black


People also ask

How do I delete a bind address already in use?

The Error “address already in use” occurred because some process was already running on the same port. So we can resolve the issue just by killing the process. To stop the process, we need the process ID (PID), which we can fetch using the lsof command.

Can you skip socket binding to use sockets?

No, you don't need to bind(). If you're using a TCP or UDP socket where you are planning to either connect() or send a packet to a destination with sendto(), the kernel will automatically bind the socket to a suitable port number when you try to connect or send.

Can a socket be bound to multiple ports?

Is it possible to bind one process to multiple ports? Yes. Yes, each listening (bound) port is serviced by a separate socket (as are all the connections made from each listening port). Thanks for the answer.

What is unbound socket?

If a socket has an IP address but not a port number it is said to be 'unbound'.


1 Answers

socket = new ServerSocket(0);

Will automatically select you a free port.

Furthermore, this code will tell you wether a port is avaliable:

boolean portAvaliable = true;
ServerSocket s = null;
try {
   s = new ServerSocket(yourPort);
}
catch (IOException e) {
   portAvaliable = false;
} 
finally {
   if (s != null)
      try {
        s.close();
      } 
      catch (IOException e) { 
         //handle the exception
      }
}

Check the boolean value from portAvaliable in order to identify the port status.

like image 173
aran Avatar answered Sep 29 '22 11:09

aran