我想启动一个侦听端口的服务器。我可以显式地指定端口,它工作。但我想以自动的方式找到一个端口。在这方面,我有两个问题。
我应该在哪个范围内搜索端口号?(我使用的端口是12345、12346和12347,没有问题)。 我如何知道给定的端口是否被其他软件占用?
我想启动一个侦听端口的服务器。我可以显式地指定端口,它工作。但我想以自动的方式找到一个端口。在这方面,我有两个问题。
我应该在哪个范围内搜索端口号?(我使用的端口是12345、12346和12347,没有问题)。 我如何知道给定的端口是否被其他软件占用?
当前回答
使用'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) {
}
}
参考链接。
其他回答
Eclipse SDK包含一个SocketUtil类,它可以做你想做的事情。你可以看看git的源代码。
使用'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) {
}
}
参考链接。
如果您正在使用Spring,那么由Michail Nikolaev提供的答案是最简单、最干净的,IMO应该给予好评。 为了方便起见,我将使用springframework SocketUtils.findAvailableTcpPort()方法添加一个内联示例:
int randomAvailablePort = SocketUtils.findAvailableTcpPort();
就这么简单,只有一行:)。当然,Utils类提供了许多其他有趣的方法,我建议看看文档。
如果服务器启动,则该套接字未被使用。
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实例后,不同的进程/线程可能会立即绑定到相同的端口。