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

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


当前回答

这里有很多使用ServerSocket的答案。我检查了Micronauts实现,他们转而尝试将客户端套接字连接到本地端口,如果失败,他们说端口是开放的。对我来说,这样做的好处是他们不必冒险在测试中使用端口。

它们的代码是这样的:

    public static boolean isTcpPortAvailable(int currentPort) {
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(InetAddress.getLocalHost(), currentPort), 20);
            return false;
        } catch (Throwable e) {
            return true;
        }
    }

参考网址:https://github.com/micronaut-projects/micronaut-core/blob/3.4.x/core/src/main/java/io/micronaut/core/io/socket/SocketUtils.java

其他回答

这可能对你没有太大帮助,但在我的(Ubuntu)机器上,我有一个文件/etc/services,其中至少给出了一些应用程序使用/保留的端口。这些是这些应用的标准端口。

不能保证这些端口正在运行,只是这些应用程序使用的默认端口(所以如果可能的话,你不应该使用它们)。

定义了500多个端口,大约一半是UDP,一半是TCP。

这些文件是使用IANA的信息制作的,请参见IANA指定的端口号。

使用'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) {

         }
}

参考链接。

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

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

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

int port = FreePortFinder.findFreeLocalPort();

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

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

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