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

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


当前回答

这适用于我在Java 6上的工作

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

其他回答

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

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

从Java 1.7开始,你可以像这样使用try-with-resources:

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

    }
  }

如果需要在特定接口上找到一个开放端口,请检查ServerSocket文档以获得替代构造函数。

警告:任何使用此方法返回的端口号的代码都会受到竞态条件的影响——在关闭ServerSocket实例后,不同的进程/线程可能会立即绑定到相同的端口。

使用'ServerSocket'类,我们可以确定给定的端口是正在使用还是空闲。ServerSocket提供了一个以整数(即端口号)为参数的构造函数 参数并初始化端口上的服务器套接字。如果ServerSocket抛出任何IO异常,那么我们可以假设这个端口已经被使用。

下面的代码片段用于获取所有可用端口。

for (int port = 1; port < 65535; port++) {
         try {
                  ServerSocket socket = new ServerSocket(port);
                  socket.close();
                  availablePorts.add(port);
         } catch (IOException e) {

         }
}

参考链接。

你可以让ServerSocket为你找到一个端口,然后关闭它:

private int getFreePort() {
        var freePort = 0;
        try (ServerSocket s = new ServerSocket(0)) {
            freePort = s.getLocalPort();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return freePort;
    }

Eclipse SDK包含一个SocketUtil类,它可以做你想做的事情。你可以看看git的源代码。