简体   繁体   English

如何在端口范围内找到开放端口?

[英]How can i find an open ports in range of ports?

I want to find an open local port in some range. 我想在某个范围内找到一个开放的本地端口。

How can I do that in the most efficient way, without connecting to the port. 如何在不连接端口的情况下以最有效的方式完成此操作。

If you want to find a local open port to bind a server to, then you can create a ServerSocket and if it does not throw an Exception, then it's open. 如果要查找将服务器绑定到的本地开放端口,则可以创建ServerSocket ,如果它没有抛出异常,则它是打开的。

I did the following in one of my projects: 我在其中一个项目中做了以下事情:

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 is a ThreadLocal here, but of course you can do an incrementing part there. RANDOM在这里是一个ThreadLocal ,当然你可以在那里做一个递增的部分。

There's a little problem you may face in a multitasking windows/unix environment: if some isPortAvailable(final int port) from any of the answers returns a true for you, that doesn't mean, that at the moment when you will actually bind it it still will be available. 在多任务处理的windows / unix环境中你可能遇到一些问题:如果某些答案中的某些isPortAvailable(最终的int端口)返回true,那并不意味着,当你实际绑定它时它仍然可用。 The better solution would be create a method 更好的解决方案是创建一个方法

ServerSocket tryBind(int portRangeBegin, int portRangeEnd) throws UnableToBindException;

So that you will just launch it and receive open socket for you, on some available port in the given range. 因此,您将在给定范围内的某个可用端口上启动它并接收打开的套接字。

如果您的意思是远程服务器中的端口,那么您可能需要一个支持raw-socket的库来发送同步数据包并等待sync-ack数据包,就像nmap一样。

One way to do is use some native network command and parse the output. 一种方法是使用一些本机网络命令并解析输出。

  1. You can try netstat command as its available on Windows and *nix platforms. 您可以尝试在Windows和* nix平台上使用netstat命令。
  2. Typical command would be netstat -n 典型的命令是netstat -n
  3. Its output is of following format. 其输出格式如下。 Netstat命令输出

  4. you need to parse the 'Foreign Address column for localhost or 127.0.0.1' and get a list of busy ports. 您需要解析localhost或127.0.0.1的'外部地址列'并获取繁忙端口列表。 Then see if they are in the range you specified. 然后查看它们是否在您指定的范围内。

If this is not about port-sniffing, but about service discovery, consider using a rendez-vous server (like an RMI server) or using the UDP protocol. 如果这不是关于端口嗅探,而是关于服务发现,请考虑使用rendez-vous服务器(如RMI服务器)或使用UDP协议。 Back in the day we used JXTA for this, but I hope there is a better alternative for this now. 回到当天我们使用JXTA,但我希望现在有更好的选择。

Essentially the same idea as Karaszi, but instead of constructing that many sockets, use the InetSocketAddress and try to bind a ServerSocket to every address in range, until you hit an open one. 与Karaszi基本相同的想法,但不是构建那么多套接字,而是使用InetSocketAddress并尝试将ServerSocket绑定到范围内的每个地址,直到您打开一个。

If you don't want to bind to that port (although if you don't, the socket may as well be bound the next moment after you check), use a plain Socket Object and try to connect to the ports - if it works, the port is taken, if it doesn't (and you don't have a firewall forbiding the connection), then it's most likely free. 如果您不想绑定到该端口(尽管如果不这样,也可以在检查后的下一刻绑定套接字),请使用普通的套接字对象并尝试连接到端口 - 如果它可以工作,端口被占用,如果没有(并且你没有防火墙禁止连接),那么它很可能是免费的。

Just pass zero as the port number to new ServerSocket(), then it will find one for you. 只需将零号作为端口号传递给新的ServerSocket(),然后它就会找到一个。 But you can forget about the range, it will choose from the system-defined range. 但您可以忘记范围,它将从系统定义的范围中进行选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM