我想启动一个监听端口的服务器。我可以明确指定端口并且它可以工作。但是我希望以自动方式查找可用端口。在这方面,我有两个问题。
应该在哪个端口范围内搜索可用端口号?(我使用了12345、12346和12347端口,它们都可以正常使用)。
如何确定给定的端口是否已被其他软件占用?
我想启动一个监听端口的服务器。我可以明确指定端口并且它可以工作。但是我希望以自动方式查找可用端口。在这方面,我有两个问题。
应该在哪个端口范围内搜索可用端口号?(我使用了12345、12346和12347端口,它们都可以正常使用)。
如何确定给定的端口是否已被其他软件占用?
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
创建自己的服务器,您可以让它为您选择一个空闲端口: ServerSocket serverSocket = new ServerSocket(0);
int port = serverSocket.getLocalPort();
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
// don't call: connector.setPort(port);
server.addConnector(connector);
server.start();
int port = connector.getLocalPort();
虽然可能对你帮助不大,但在我的(Ubuntu)机器上,我有一个/etc/services文件,其中至少列出了一些应用程序使用/保留的端口。这些是这些应用程序的标准端口。
不能保证这些正在运行,只是这些应用程序使用的默认端口(因此如果可能的话,您不应该使用它们)。
定义了略多于500个端口,约一半为UDP,一半为TCP。
这些文件使用IANA的信息制作而成,请参见IANA分配的端口号。
int randomAvailablePort = SocketUtils.findAvailableTcpPort();
就这么简单,只需要一行代码 :) 当然,Utils类还提供许多其他有趣的方法,建议查看文档。
private Integer laancNotifyPort = SocketUtils.findAvailableTcpPort();
您还可以设置一个可接受的范围,它将在此范围内搜索:
private Integer laancNotifyPort = SocketUtils.findAvailableTcpPort(9090, 10090);
这是一个方便的方法,它抽象了复杂性,但在内部与此线程上的许多其他答案类似。
这里有很多使用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;
}
}
for (int port = 1; port < 65535; port++) {
try {
ServerSocket socket = new ServerSocket(port);
socket.close();
availablePorts.add(port);
} catch (IOException e) {
}
}
参考资料 link。
public static int findAvailableTcpPort() {
int minPort = 1024;
int maxPort = 65535;
int portRange = maxPort - minPort;
int maxAttempts = 1000;
int candidatePort;
int searchCounter = 0;
Random random = new Random(System.nanoTime());
do {
if (searchCounter > maxAttempts) {
throw new IllegalStateException(String.format(
"Could not find an available TCP port in the range [%d, %d] after %d attempts",
minPort, maxPort, maxAttempts));
}
candidatePort = minPort + random.nextInt(portRange + 1);
searchCounter++;
} while (!isPortAvailable(candidatePort));
return candidatePort;
}
private static boolean isPortAvailable(int port) {
try {
ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(port, 1, InetAddress.getByName("localhost"));
serverSocket.close();
return true;
} catch (Exception ex){
return false;
}
}
你可以请求ServerSocket为你找一个端口,然后关闭它:
private int getFreePort() {
var freePort = 0;
try (ServerSocket s = new ServerSocket(0)) {
freePort = s.getLocalPort();
} catch (Exception e) {
e.printStackTrace();
}
return freePort;
}