Prevent the application from binding to a socket that is already connected

How to prevent a Java application from binding to a socket that another process in Windows is still connected to?

I have a problem when I have a Java application that listens on port 80. The application starts normally and does not report any exceptions. I could not understand why I could not connect to port 80. Other ports worked fine. I checked netstat for other processes listening on 80 and found Skype. I did not think this was possible, but after some research, I assume that Skype is listening with the SO_REUSEADDR option. In this state, the receiving application is undefined. I would like my Java application to fail in this case with a bind exception (or another).

It looks like I could use SO_EXCLUSIVEADDRUSE if I had access to this option through Java, but I don't think it is possible. There are a lot of questions and answers on SO_REUSEADDR, but I could not find the answers to my question. This is not only about Skype (I can turn off listening), I want my program to be more reliable in this situation.

This is a snippet from netstat -abn in a Windows 7 window:

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 assume that Skype uses SO_REUSEADDR

Processes are not displayed on different interfaces.

Here is a snippet of code. Port is 80:

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

As additional information, I created a sample program to minimize any side effects or incorrect 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 do not get an exception when starting this sample program (PortTest) and when starting Skype and listening on port 80. And for further verification, I performed a second instance of PortTest, and I see that the port is used in the 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) 
+6
source share
1 answer
 socket = new ServerSocket(0); 

A free port will be automatically selected.

In addition, this code will tell you that the port is available:

 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 } 
+2
source

Source: https://habr.com/ru/post/945178/


All Articles