我想启动一个侦听端口的服务器。我可以显式地指定端口,它工作。但我想以自动的方式找到一个端口。在这方面,我有两个问题。
我应该在哪个范围内搜索端口号?(我使用的端口是12345、12346和12347,没有问题)。 我如何知道给定的端口是否被其他软件占用?
我想启动一个侦听端口的服务器。我可以显式地指定端口,它工作。但我想以自动的方式找到一个端口。在这方面,我有两个问题。
我应该在哪个范围内搜索端口号?(我使用的端口是12345、12346和12347,没有问题)。 我如何知道给定的端口是否被其他软件占用?
当前回答
你可以让ServerSocket为你找到一个端口,然后关闭它:
private int getFreePort() {
var freePort = 0;
try (ServerSocket s = new ServerSocket(0)) {
freePort = s.getLocalPort();
} catch (Exception e) {
e.printStackTrace();
}
return freePort;
}
其他回答
如果您正在使用Spring,那么由Michail Nikolaev提供的答案是最简单、最干净的,IMO应该给予好评。 为了方便起见,我将使用springframework SocketUtils.findAvailableTcpPort()方法添加一个内联示例:
int randomAvailablePort = SocketUtils.findAvailableTcpPort();
就这么简单,只有一行:)。当然,Utils类提供了许多其他有趣的方法,我建议看看文档。
这适用于我在Java 6上的工作
ServerSocket serverSocket = new ServerSocket(0);
System.out.println("listening on port " + serverSocket.getLocalPort());
这可能对你没有太大帮助,但在我的(Ubuntu)机器上,我有一个文件/etc/services,其中至少给出了一些应用程序使用/保留的端口。这些是这些应用的标准端口。
不能保证这些端口正在运行,只是这些应用程序使用的默认端口(所以如果可能的话,你不应该使用它们)。
定义了500多个端口,大约一半是UDP,一半是TCP。
这些文件是使用IANA的信息制作的,请参见IANA指定的端口号。
这里有很多使用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
如果您将0作为端口号传递给ServerSocket的构造函数,它将为您分配一个端口。