我想启动一个侦听端口的服务器。我可以显式地指定端口,它工作。但我想以自动的方式找到一个端口。在这方面,我有两个问题。
我应该在哪个范围内搜索端口号?(我使用的端口是12345、12346和12347,没有问题)。 我如何知道给定的端口是否被其他软件占用?
我想启动一个侦听端口的服务器。我可以显式地指定端口,它工作。但我想以自动的方式找到一个端口。在这方面,我有两个问题。
我应该在哪个范围内搜索端口号?(我使用的端口是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
其他回答
欧洲经济区ServerSocket:
创建绑定到指定端口的服务器套接字。端口为0在任何空闲端口上创建套接字。
如果服务器启动,则该套接字未被使用。
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));
}
这里有很多使用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
如果您需要在范围内使用:
public int nextFreePort(int from, int to) {
int port = randPort(from, to);
while (true) {
if (isLocalPortFree(port)) {
return port;
} else {
port = ThreadLocalRandom.current().nextInt(from, to);
}
}
}
private boolean isLocalPortFree(int port) {
try {
new ServerSocket(port).close();
return true;
} catch (IOException e) {
return false;
}
}
根据维基百科,如果你不需要一个“众所周知”的端口,你应该使用端口49152到65535。
判断一个端口是否正在使用的唯一方法是尝试打开它。