在 Java 中查找空闲端口
Find free port in Java
我需要在 Java 应用程序中找到空闲端口。为什么下面的代码不起作用?它总是 returns 0.
public int findFreePort() {
int portNumber = new InetSocketAddress(0).getPort();
return portNumber;
}
Java new InetSocketAddress()
的文档说:
创建一个套接字地址,其中 IP 地址是通配符地址,端口号是指定值。
有效端口值介于 0 和 65535 之间。端口号为零将使系统在绑定操作中选择一个临时端口。
实际上你输出的是你在构造函数中指定的端口成员。所以 0
是预期的。
javadoc 声明该端口将让系统为绑定操作选择一个临时端口。
它并没有告诉端口号将直接在 InetSocketAddress
实例中使用临时端口进行评估。
实际上你并没有对这个 InetSocketAddress
实例执行绑定操作。
很明显,您没有 open/create 套接字通道来与此实例通信。
所以你无法注意到端口的结果。
例如,这将 ServerSocket
绑定到 InetSocketAddress
:
ServerSocket ss = new ServerSocket(..);
ss.bind(new InetSocketAddress(0));
这里有一个更完整的例子来说明事情是如何工作的:
public class InetSockerAddressWithEphemeralPortMain {
public static void main(String[] args) throws InterruptedException, IOException {
InetSocketAddress randomSocketAddressFirst = new InetSocketAddress(0);
try (ServerSocket ssOne = new ServerSocket()) {
System.out.println("randomSocketAddress port before any binding : " + randomSocketAddressFirst.getPort());
ssOne.bind(randomSocketAddressFirst);
System.out.println("local port after first binding :" + ssOne.getLocalPort());
}
try (ServerSocket ssTwo = new ServerSocket()) {
ssTwo.bind(randomSocketAddressFirst);
System.out.println("local port after second binding :" + ssTwo.getLocalPort());
System.out.println("randomSocketAddress port after all bindings : " + randomSocketAddressFirst.getPort());
}
}
}
输出:
randomSocketAddress port before any binding : 0
local port after first binding : 65110
local port after second binding : 65111
randomSocketAddress port after all bindings : 0
您可以看到 InetSocketAddress
对象始终保持 0
作为端口值,而 ServerSocket
对象受益于临时端口。
如果您只想找到一个空闲端口以在您的代码中使用,请执行以下操作:
private static int findFreePort() {
int port = 0;
// For ServerSocket port number 0 means that the port number is automatically allocated.
try (ServerSocket socket = new ServerSocket(0)) {
// Disable timeout and reuse address after closing the socket.
socket.setReuseAddress(true);
port = socket.getLocalPort();
} catch (IOException ignored) {}
if (port > 0) {
return port;
}
throw new RuntimeException("Could not find a free port");
}
我需要在 Java 应用程序中找到空闲端口。为什么下面的代码不起作用?它总是 returns 0.
public int findFreePort() {
int portNumber = new InetSocketAddress(0).getPort();
return portNumber;
}
Java new InetSocketAddress()
的文档说:
创建一个套接字地址,其中 IP 地址是通配符地址,端口号是指定值。
有效端口值介于 0 和 65535 之间。端口号为零将使系统在绑定操作中选择一个临时端口。
实际上你输出的是你在构造函数中指定的端口成员。所以 0
是预期的。
javadoc 声明该端口将让系统为绑定操作选择一个临时端口。
它并没有告诉端口号将直接在 InetSocketAddress
实例中使用临时端口进行评估。
实际上你并没有对这个 InetSocketAddress
实例执行绑定操作。
很明显,您没有 open/create 套接字通道来与此实例通信。
所以你无法注意到端口的结果。
例如,这将 ServerSocket
绑定到 InetSocketAddress
:
ServerSocket ss = new ServerSocket(..);
ss.bind(new InetSocketAddress(0));
这里有一个更完整的例子来说明事情是如何工作的:
public class InetSockerAddressWithEphemeralPortMain {
public static void main(String[] args) throws InterruptedException, IOException {
InetSocketAddress randomSocketAddressFirst = new InetSocketAddress(0);
try (ServerSocket ssOne = new ServerSocket()) {
System.out.println("randomSocketAddress port before any binding : " + randomSocketAddressFirst.getPort());
ssOne.bind(randomSocketAddressFirst);
System.out.println("local port after first binding :" + ssOne.getLocalPort());
}
try (ServerSocket ssTwo = new ServerSocket()) {
ssTwo.bind(randomSocketAddressFirst);
System.out.println("local port after second binding :" + ssTwo.getLocalPort());
System.out.println("randomSocketAddress port after all bindings : " + randomSocketAddressFirst.getPort());
}
}
}
输出:
randomSocketAddress port before any binding : 0
local port after first binding : 65110
local port after second binding : 65111
randomSocketAddress port after all bindings : 0
您可以看到 InetSocketAddress
对象始终保持 0
作为端口值,而 ServerSocket
对象受益于临时端口。
如果您只想找到一个空闲端口以在您的代码中使用,请执行以下操作:
private static int findFreePort() {
int port = 0;
// For ServerSocket port number 0 means that the port number is automatically allocated.
try (ServerSocket socket = new ServerSocket(0)) {
// Disable timeout and reuse address after closing the socket.
socket.setReuseAddress(true);
port = socket.getLocalPort();
} catch (IOException ignored) {}
if (port > 0) {
return port;
}
throw new RuntimeException("Could not find a free port");
}