How to find an available port?

强颜欢笑 提交于 2019-12-27 16:40:53

问题


I want to start a server which listen to a port. I can specify port explicitly and it works. But I would like to find a port in an automatic way. In this respect I have two questions.

  1. In which range of port numbers should I search for? (I used ports 12345, 12346, and 12347 and it was fine).

  2. How can I find out if a given port is not occupied by another software?


回答1:


If you don't mind the port used, specify a port of 0 to the ServerSocket constructor and it will listen on any free port.

ServerSocket s = new ServerSocket(0);
System.out.println("listening on port: " + s.getLocalPort());

If you want to use a specific set of ports, then the easiest way is probably to iterate through them until one works. Something like this:

public ServerSocket create(int[] ports) throws IOException {
    for (int port : ports) {
        try {
            return new ServerSocket(port);
        } catch (IOException ex) {
            continue; // try next port
        }
    }

    // if the program gets here, no port in the range was found
    throw new IOException("no free port found");
}

Could be used like so:

try {
    ServerSocket s = create(new int[] { 3843, 4584, 4843 });
    System.out.println("listening on port: " + s.getLocalPort());
} catch (IOException ex) {
    System.err.println("no available ports");
}



回答2:


If you pass 0 as the port number to the constructor of ServerSocket, It will allocate a port for you.




回答3:


Starting from Java 1.7 you can use try-with-resources like this:

  private Integer findRandomOpenPortOnAllLocalInterfaces() throws IOException {
    try (
        ServerSocket socket = new ServerSocket(0);
    ) {
      return socket.getLocalPort();

    }
  }

If you need to find an open port on a specific interface check ServerSocket documentation for alternative constructors.

Warning: Any code using the port number returned by this method is subject to a race condition - a different process / thread may bind to the same port immediately after we close the ServerSocket instance.




回答4:


According to Wikipedia, you should use ports 49152 to 65535 if you don't need a 'well known' port.

AFAIK the only way to determine wheter a port is in use is to try to open it.




回答5:


If you need in range use:

public int nextFreePort(int from, int to) {
    int port = randPort(from, to);
    while (true) {
        if (isLocalPortFree(port)) {
            return port;
        } else {
            port = ThreadLocalRandom.current().nextInt(from, to);
        }
    }
}

private boolean isLocalPortFree(int port) {
    try {
        new ServerSocket(port).close();
        return true;
    } catch (IOException e) {
        return false;
    }
}



回答6:


If you use Spring you may try http://docs.spring.io/spring/docs/4.0.5.RELEASE/javadoc-api/org/springframework/util/SocketUtils.html#findAvailableTcpPort--




回答7:


The Eclipse SDK contains a class SocketUtil, that does what you want. You may have a look into the git source code.




回答8:


See http://java.sun.com/j2se/1.4.2/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29

Creates a server socket, bound to the specified port. A port of 0 creates a socket on any free port.




回答9:


This works for me on Java 6

    ServerSocket serverSocket = new ServerSocket(0);
    System.out.println("listening on port " + serverSocket.getLocalPort());



回答10:


I have recently released a tiny library for doing just that with tests in mind. Maven dependency is:

<dependency>
    <groupId>me.alexpanov</groupId>
    <artifactId>free-port-finder</artifactId>
    <version>1.0</version>
</dependency>

Once installed, free port numbers can be obtained via:

int port = FreePortFinder.findFreeLocalPort();



回答11:


If you want to create your own server using a ServerSocket, you can just have it pick a free port for you:

  ServerSocket serverSocket = new ServerSocket(0);
  int port = serverSocket.getLocalPort();

Other server implementations typically have similar support. Jetty for example picks a free port unless you explicitly set it:

  Server server = new Server();
  ServerConnector connector = new ServerConnector(server);
  // don't call: connector.setPort(port);
  server.addConnector(connector);
  server.start();
  int port = connector.getLocalPort();



回答12:


It may not help you much, but on my (Ubuntu) machine I have a file /etc/services in which at least the ports used/reserved by some of the apps are given. These are the standard ports for those apps.

No guarantees that these are running, just the default ports these apps use (so you should not use them if possible).

There are slightly more than 500 ports defined, about half UDP and half TCP.

The files are made using information by IANA, see IANA Assigned port numbers.




回答13:


If your server starts up, then that socket was not used.

EDIT

Something like:

ServerSocket s = null ;

try { 
    s = new ServerSocket( 0 ); 
} catch( IOException ioe ){
   for( int i = START; i < END ; i++ ) try {
        s = new ServerSocket( i );
    } catch( IOException ioe ){}
}
// At this point if s is null we are helpless
if( s == null ) {
    throw new IOException(
       Strings.format("Unable to open server in port range(%d-%d)",START,END));
}



回答14:


If you are using Spring, the answer provided by Michail Nikolaev is the simplest and cleanest one, and IMO should be upvoted. Just for convenience purposes, I'll add an inline example using the Springframwework SocketUtils.findAvailableTcpPort() method:

int randomAvailablePort = SocketUtils.findAvailableTcpPort();

It's as easy as that, just one line :). Of course, the Utils class offer many other interesting methods, I suggest having a look at the docs.



来源:https://stackoverflow.com/questions/2675362/how-to-find-an-available-port

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