Techioz Blog

Ruby - ポートが開いているかどうかを確認する

概要

特定のポートが 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 例外がスローされる (ポートが閉じている場合) という欠点があります。私の質問は次のとおりです。

このコードを 1 秒間だけ待機するように修正することはできますか (それまでに何も返されない場合は false を返す)、または特定のホストで特定のポートが開いているかどうかを確認するより良い方法はありますか?

編集: 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