我想启动一个侦听端口的服务器。我可以显式地指定端口,它工作。但我想以自动的方式找到一个端口。在这方面,我有两个问题。

我应该在哪个范围内搜索端口号?(我使用的端口是12345、12346和12347,没有问题)。 我如何知道给定的端口是否被其他软件占用?


当前回答

如果你想使用ServerSocket创建你自己的服务器,你可以让它为你选择一个空闲端口:

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

其他服务器实现通常也有类似的支持。例如,Jetty选择一个空闲端口,除非你显式地设置它:

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

其他回答

如果不介意使用的端口,可以向ServerSocket构造函数指定一个端口0,它将侦听任何空闲端口。

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

如果您希望使用一组特定的端口,那么最简单的方法可能是遍历它们,直到其中一个可以工作为止。就像这样:

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");
}

可以这样使用:

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");
}

如果您使用Spring,您可以尝试http://docs.spring.io/spring/docs/4.0.5.RELEASE/javadoc-api/org/springframework/util/SocketUtils.html#findAvailableTcpPort--

如果您需要在范围内使用:

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;
    }
}

如果服务器启动,则该套接字未被使用。

EDIT

喜欢的东西:

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));
}

如果你想使用ServerSocket创建你自己的服务器,你可以让它为你选择一个空闲端口:

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

其他服务器实现通常也有类似的支持。例如,Jetty选择一个空闲端口,除非你显式地设置它:

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