我想在某个范围内找到一个开放的本地端口。
如何在不连接端口的情况下以最有效的方式实现这一目标。
答案 0 :(得分:6)
如果要查找将服务器绑定到的本地开放端口,则可以创建ServerSocket
,如果它没有抛出异常,则它会打开。
我在我的一个项目中做了以下事情:
private int getAvailablePort() throws IOException {
int port = 0;
do {
port = RANDOM.get().nextInt(20000) + 10000;
} while (!isPortAvailable(port));
return port;
}
private boolean isPortAvailable(final int port) throws IOException {
ServerSocket ss = null;
try {
ss = new ServerSocket(port);
ss.setReuseAddress(true);
return true;
} catch (final IOException e) {
} finally {
if (ss != null) {
ss.close();
}
}
return false;
}
RANDOM
在这里是ThreadLocal
,但当然你可以在那里做一个增量部分。
答案 1 :(得分:3)
在多任务处理windows / unix环境中可能会遇到一些问题:如果某些答案中的某些isPortAvailable(最终的int端口)返回true,那并不意味着,此时您将会实际绑定它仍然可用。更好的解决方案是创建方法
ServerSocket tryBind(int portRangeBegin, int portRangeEnd) throws UnableToBindException;
这样您就可以在给定范围内的某个可用端口上启动它并接收打开的套接字。
答案 2 :(得分:1)
如果您指的是远程服务器中的端口,那么您可能需要一个支持raw-socket的库来发送同步数据包并等待sync-ack数据包,就像nmap那样。
答案 3 :(得分:0)
一种方法是使用一些本机网络命令并解析输出。
netstat -n
其输出格式如下。
您需要解析“localhost或127.0.0.1的外部地址”列并获取繁忙端口列表。然后查看它们是否在您指定的范围内。
答案 4 :(得分:0)
如果这不是关于端口嗅探,而是关于服务发现,请考虑使用rendez-vous服务器(如RMI服务器)或使用UDP协议。回到当天,我们使用了JXTA,但我希望现在有更好的选择。
答案 5 :(得分:0)
与Karaszi基本相同的想法,但不是构建那么多套接字,而是使用InetSocketAddress并尝试将ServerSocket绑定到范围内的每个地址,直到你打开一个。
如果您不想绑定到该端口(尽管如果不这样,也可以在检查后的下一刻绑定套接字),请使用普通的套接字对象并尝试连接到端口 - 如果它工作,端口被采用,如果没有(并且你没有防火墙禁止连接),那么它很可能是免费的。
答案 6 :(得分:0)
只需将零号作为端口号传递给新的ServerSocket(),然后它就会找到一个。但是您可以忘记范围,它将从系统定义的范围中进行选择。