【问题标题】:Get a random, high port number that is still available获取仍然可用的随机高端口号
【发布时间】:2009-06-04 01:14:06
【问题描述】:

假设我想在 IPC 的某个端口上运行 TCP/IP 服务。当我将端口号传递给我想要与之通信的进程时,端口号并不重要。获取系统仍然可用的随机、高(通常 > 49152)端口号的最佳方法是什么? POSIX 中有什么我可以使用的吗?

我知道 FTP 服务器经常需要这个。

【问题讨论】:

    标签: sockets posix tcp


    【解决方案1】:

    如果您不指定端口号,操作系统会自动为您选择一个ephemeral port 号码。

    来自Choosing the Port Number

    新的服务器软件应努力避免依赖于特定的端口号,尤其是当它是用户级软件时,它并非不可避免地绑定到众所周知的端口。幸运的是,这很容易通过请求端口 0 来完成,它会指示系统选择一个临时端口号。

    【讨论】:

    • 是的,端口 0 允许操作系统为您选择一个随机可用端口。另一方面,使用端口 0 不允许您为操作系统指定一系列端口以供选择。例如,如果您位于防火墙/路由器后面,那么能够使用端口范围就变得更加重要。
    • @RemyLebeau 任何配置为仅允许一定范围的出站端口的防火墙都配置错误,应予以修复。由于 Socket API 不支持这一点,它给应用程序带来了无法满足的负担,并且从安全角度来看完全没有意义。
    • @EJP:您假设端口绑定仅针对 出站 连接进行。 FTP 是一个很好的例子,说明客户端何时可能需要为 inbound 连接绑定套接字以进行主动模式传输。
    【解决方案2】:

    临时端口可以做到这一点。您的操作系统会从空闲端口池中为您分配一个端口。

    有一些 C 代码,BSD 许可,这样做here

    在 Python 中,您可以为相同目的指定 ('', 0) socket.AF_INET 地址对,例如sock.bind(('', 0))

    【讨论】:

    • 我们应该使用参数调用哪个 Python 函数 ('127.0.0.1', 0)?
    • @Nordlöw - bind
    【解决方案3】:

    如果您尝试绑定到端口号 0,系统会将您的套接字绑定到“临时”随机端口。 然后,您可以使用getsockname(在 C 中)获取端口。

    在红宝石中:

    s = TCPServer.new('localhost', 0) #You can also use nil instead of 0
    s.addr[1] #The obtained port number
    

    【讨论】:

    • 短暂的?它会持续多久?我希望在服务器停止之前。
    • @yucer 这意味着它不是与特定固定服务相关的固定数字,例如 HTTP 的 80。它仍然会持续到您关闭或当您的进程终止时操作系统为您关闭它。
    • 我认为构造函数已经改变。见:bit.ly/1o9DDJb addr 属性现在是 server_address
    • @yucer ruby​​ != python
    【解决方案4】:

    您可以使用我的小型 C 库:https://github.com/yegor256/random-tcp-port

    编译它并在您的机器上运行。它将输出一个随机可用的 TCP 端口。

    【讨论】:

    • 一旦退出,它将立即再次可供其他人使用。这完全没有意义。
    • 但这正是您在下面建议的几个答案,所有其他回答者也建议:) 我的库只是让获取变得更容易
    • 你做错了。分配随机端口已经是系统的一部分——您所要做的就是请求端口号 0,您将获得一个随机端口,您可以使用getsockname 获得该端口。但是,如果您关闭套接字,则无法保证旧的临时端口号仍然可用。
    • @yegor256 是的,不要分开绑定和找随机端口,简单绑定到端口0。
    • @PSkocik 如果需要分离绑定和查找怎么办?这就是我的工具的用途。
    【解决方案5】:

    唯一的方法是遍历所需的端口范围,尝试一次将一个套接字绑定到每个端口,直到找到一个成功的端口。

    【讨论】:

    • 不,这不是唯一的方法。绑定到端口 0 是另一种方式,也是一种更好的方式。 QED
    猜你喜欢
    • 2020-10-07
    • 2014-01-14
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 2021-07-28
    • 1970-01-01
    相关资源
    最近更新 更多