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)