Ruby - See if a port is open

All other existing answer are undesirable. Using Timeout is discouraged. Perhaps things depend on ruby version. At least since 2.0 one can simply use:

Socket.tcp("www.ruby-lang.org", 10567, connect_timeout: 5) {}

For older ruby the best method I could find is using non-blocking mode and then select. Described here:

  • https://spin.atomicobject.com/2013/09/30/socket-connection-timeout-ruby/

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

I recently came up with this solution, making use of the unix lsof command:

def port_open?(port)
  !system("lsof -i:#{port}", out: '/dev/null')
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