我需要一个快速的方法来确定给定的端口是否是用Ruby打开的.我现在正在摆弄这个:

require 'socket'

def is_port_open?(ip, port)
  begin
    TCPSocket.new(ip, port)
  rescue Errno::ECONNREFUSED
    return false
  end
  return true
end

如果端口是打开的,它工作得很好,但它的缺点是,偶尔它会静坐等待10-20秒,然后最终超时,抛出ETIMEOUT个异常(如果端口关闭).因此,我的问题是:

是否可以将此代码修改为只等待一秒钟(如果我们当时没有收到任何回复,则返回false),或者是否有更好的方法来判断给定主机上的给定端口是否打开?

Edit:调用bash代码也是可以接受的,只要它能跨平台工作(例如Mac OS X、*nix和Cygwin),尽管我更喜欢Ruby代码.

推荐答案

以下类似的方法可能会奏效:

require 'socket'
require 'timeout'

def is_port_open?(ip, port)
  begin
    Timeout::timeout(1) do
      begin
        s = TCPSocket.new(ip, port)
        s.close
        return true
      rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
        return false
      end
    end
  rescue Timeout::Error
  end

  return false
end

Ruby相关问答推荐

设计登录根路由rails 3

Ruby $:.unshift File.dirname(__FILE__)

如何使 Sinatra 通过 HTTPS/SSL 工作?

Ruby 将字符串转换为方法名

判断Ruby中的目录是否为空

在 RSpec-2.11 中使用隐含的 `subject` 和 `expect`

Ruby:如何卸载设计(uninstall Devise)?

如何在 ruby​​ 中编写负循环,例如 for(i=index; i >= 0; i --)

有没有比 Rspec 的 `should_receive` 更少干扰的替代方法?

在 ruby​​ 中访问嵌套哈希的元素

您如何将 Cucumber 场景标记为待处理

如何在 Ruby 中使用 (n) 诅咒?

什么时候在 Ruby 中使用 Struct 比使用 Hash 更好?

如何删除字符串中的重复空格?

从字符串中删除所有特殊字符 - ruby

你能在 Python 的核心类型上修改补丁方法吗?

Ruby 中的 %w{} 和 %W{} 大写和小写百分比 W 数组文字有什么区别?

如何在 Ruby 的 IRB 中启用自动完成

为什么在安装 gem 时出现权限被拒绝错误?

查找与给定条件匹配的元素的索引