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

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


当前回答

欧洲经济区ServerSocket:

创建绑定到指定端口的服务器套接字。端口为0在任何空闲端口上创建套接字。

其他回答

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

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

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

我最近发布了一个小型库,专门用于测试。 Maven依赖关系是:

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

安装完成后,可通过以下方式获取空闲端口号:

int port = FreePortFinder.findFreeLocalPort();

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

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

        return freePort;
    }

如果不介意使用的端口,可以向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");
}