如何使用 Ruby 找到免费的 TCP 服务器端口?

Posted

技术标签:

【中文标题】如何使用 Ruby 找到免费的 TCP 服务器端口?【英文标题】:How do you find a free TCP server port using Ruby? 【发布时间】: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 秒。

【问题讨论】:

【参考方案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。

【讨论】:

查看(新)问题的最后一段。 这不应该是公认的答案;请参阅下面的***.com/a/201528/3528。

以上是关于如何使用 Ruby 找到免费的 TCP 服务器端口?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用“C”在 Windows 中找到空闲的 TCP 端口

如何使用 NetTcpBinding (WCF) 找到可用的 TCP 端口(以便服务器可以绑定到它)

免费内网映射外网绑定,tcp端口转发(windows)

kali如何开启tcp4444端口

如何使用SOCKS5代理服务器?

在 windows 中,如何使用 c++ 检查端口是不是免费