0

我正在尝试检查给定主机是否已启动、运行和侦听特定端口,并正确处理任何错误。

我发现了许多关于 Ruby 套接字编程的参考资料,但似乎没有一个能够有效地处理“套接字超时”。我试过IO.select了,它有四个参数,其中最后一个是超时值:

IO.select([TCPSocket.new('example.com', 22)], [nil], [nil], 4)

问题是,它被卡住了,特别是如果端口号错误或服务器没有监听它。所以,最后我得到了这个,我不太喜欢它,但做了这份工作:

require 'socket'
require 'timeout'
dns = "example.com"

begin
    Timeout::timeout(3) { TCPSocket.new(dns, 22) }
    puts "Responded!!"
    # do some stuff here...
rescue SocketError
    puts "No connection!!"
    # do some more stuff here...
rescue Timeout::Error
    puts "No connection, timed out!!"
    # do some other stuff here...
end

有没有更好的方法来做到这一点?

4

2 回答 2

1

任何资源可用性的最佳测试是尝试使用它。添加额外的代码来尝试提前预测使用是否会起作用必然会失败:

  1. You test the wrong thing and get a different answer.
  2. You test the right thing but at the wrong time, and the answer changes between the test and the use, and your application performs double the work for nothing, and you write redundant code.
  3. The code you have to write to handle the test failure is identical to the code you should write to handle the use-failure. Why write that twice?
于 2013-07-30T23:52:00.870 回答
0

我们在其中一个系统中广泛使用了 Net::SSH,但遇到了超时问题。

可能最大的解决方法是实现该select方法的使用,设置低级超时,而不是尝试使用基于线程的 Timeout 类。

如何在 Ruby 中设置套接字超时? ”和“通过 SO_RCVTIMEO 套接字选项在 Ruby 中设置套接字超时”有代码可以对此进行调查。此外,其中一个指向“ Ruby 中的套接字超时”的链接具有有用的代码,但请注意它是为 Ruby 1.8.6 编写的。

Ruby 的版本也可以有所作为。1.9 之前的线程无法停止阻塞的 IP 会话,因此代码会挂起,直到套接字超时,然后超时会触发。上述两个问题都超过了这一点。

于 2013-07-31T14:02:42.680 回答