如何使用 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 端口