【问题标题】:How do you find a free TCP server port using Ruby?如何使用 Ruby 找到免费的 TCP 服务器端口?
【发布时间】:2010-09-17 01:27:56
【问题描述】:

我正在尝试创建一个一次性 HTTP 服务器来处理单个回调,并且在 Ruby 中寻找空闲 TCP 端口时需要帮助。

这是我正在做的事情的骨架:

require 'socket'
t = STDIN.read
port = 8081
while s = TCPServer.new('127.0.0.1', port).accept
  puts s.gets
  s.print "HTTP/1.1 200/OK\rContent-type: text/plain\r\n\r\n" + t
  s.close
  exit
end

(它将标准输入回显到第一个连接,然后死掉。)

如何自动找到空闲端口进行监听?

这似乎是在远程服务器上启动作业的唯一方法,然后使用唯一的作业 ID 进行回调。然后可以查询此作业 ID 以获取状态信息。为什么最初的设计师在安排工作时不能只返回工作 ID,我永远不会知道。不能使用单个端口,因为可能会与多个回调发生冲突;这样,端口仅使用 +- 5 秒。

【问题讨论】:

    标签: ruby http sockets


    【解决方案1】:

    为端口号传递 0。这将导致系统从临时端口范围中为您选择一个端口。创建服务器后,您可以向它询问其地址,该地址将包含服务器绑定到的端口。

    server = TCPServer.new('127.0.0.1', 0)
    port = server.addr[1]
    

    【讨论】:

    • 我正在使用一个基本的 Socket(不是 TCPSocket),它没有 addr 方法。你会碰巧知道在这种情况下我如何获得端口吗?
    • 回答我自己的问题,使用socket.getsockname.unpack("snA*")[1]
    【解决方案2】:

    如果您不尝试在一行中完成所有操作,这实际上很容易:-/

    require 'socket'
    t = STDIN.read
    
    port = 8080 # preferred port
    begin
      server = TCPServer.new('127.0.0.1', port)    
    rescue Errno::EADDRINUSE
      port = rand(65000 - 1024) + 1024
      retry
    end
    
    # Start remote process with the value of port
    
    socket = server.accept
    puts socket.gets
    socket.print "HTTP/1.1 200/OK\rContent-type: text/plain\r\n\r\n" + t
    socket.close
    

    这完成(强词)与问题中的 sn-p 相同。

    【讨论】:

    • 只是吹毛求疵...像这样随机选择是一个无限循环,理论上可以在服务器上运行不确定的时间;已经使用的端口越多,情况就越糟糕。
    【解决方案3】:

    你可以试试random-port,一个简单的Ruby gem(我是作者):

    require 'random-port'
    port = RandomPort::Pool.new.aquire
    

    不过,最好的方法是在之后发布它:

    RandomPort::Pool::SINGLETON.new.acquire do |port|
      # Use the TCP port, it will be returned back
      # to the pool afterward.
    end
    

    池是线程安全的,它保证端口不会被其他线程或应用程序中的任何其他地方使用,直到它被释放。

    【讨论】:

      【解决方案4】:

      也许你想测试一个端口正在监听的天气,以下对我有用 system('(6<>/dev/tcp/127.0.0.1/9292) &>/dev/null'),如果9292正在监听,则返回true,否则返回false。

      【讨论】:

        【解决方案5】:

        不要在随机端口上通信。选择一个默认值并使其可配置。随机端口与防火墙不兼容。 FTP 做到了这一点,而防火墙对它的支持简直就是一场噩梦——它必须深入检查数据包。

        【讨论】:

        • 问题是如何找到一个空闲端口来使用,而不是使用随机端口是否是个好主意。
        • 并非所有 TCP/IP 流量都通过防火墙。
        【解决方案6】:

        我想你可以依次尝试所有大于 5000 的端口(例如)。但是您将如何与客户端程序通信您正在侦听的端口?如果您需要在不同的环境之间移动脚本,决定端口并使其易于配置似乎更简单。

        对于 HTTP,标准端口是 80。我见过使用的替代端口是 8080、880 和 8000。

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-18
        • 2012-05-04
        • 1970-01-01
        • 1970-01-01
        • 2014-03-23
        • 2017-09-18
        • 2010-12-20
        • 2015-05-29
        相关资源
        最近更新 更多