I need a quick way to find out if a given port is open with Ruby. I currently am fiddling around with this:
require 'socket' def is_port_open?(ip, port) begin TCPSocket.new(ip, port) rescue Errno::ECONNREFUSED return false end return true end
It works great if the port is open, but the downside of this is that occasionally it will just sit and wait for 10-20 seconds and then eventually time out, throwing a
ETIMEOUT exception (if the port is closed). My question is thus:
Can this code be amended to only wait for a second (and return
false if we get nothing back by then) or is there a better way to check if a given port is open on a given host?
Edit: Calling bash code is acceptable also as long as it works cross-platform (e.g., Mac OS X, *nix, and Cygwin), although I do prefer Ruby code.
Something like the following might work:
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
More Ruby idiomatic syntax:
require 'socket' require 'timeout' def port_open?(ip, port, seconds=1) Timeout::timeout(seconds) do begin TCPSocket.new(ip, port).close true rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH false end end rescue Timeout::Error false end