Created
January 23, 2017 10:11
-
-
Save mrThe/14f44580e7c1e4f44692bf293a816efd to your computer and use it in GitHub Desktop.
Ruby #port_open?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def port_open?(host, port, timeout = 5) | |
addr = Socket.getaddrinfo(host, nil) | |
sockaddr = Socket.pack_sockaddr_in(port, addr[0][3]) | |
Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0).tap do |socket| | |
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) | |
begin | |
# Initiate the socket connection in the background. If it doesn't fail | |
# immediatelyit will raise an IO::WaitWritable (Errno::EINPROGRESS) | |
# indicating the connection is in progress. | |
socket.connect_nonblock(sockaddr) | |
rescue IO::WaitWritable | |
# IO.select will block until the socket is writable or the timeout | |
# is exceeded - whichever comes first. | |
if IO.select(nil, [socket], nil, timeout) | |
begin | |
# Verify there is now a good connection | |
socket.connect_nonblock(sockaddr) | |
rescue Errno::ECONNRESET | |
# coz fuck this, i don't care | |
return false | |
rescue Errno::ECONNREFUSED | |
# coz fuck this, i don't care | |
return false | |
rescue Errno::EISCONN | |
# Good news everybody, the socket is connected! | |
rescue | |
# An unexpected exception was raised - the connection is no good. | |
socket.close | |
raise | |
end | |
else | |
# IO.select returns nil when the socket is not ready before timeout | |
# seconds have elapsed | |
socket.close | |
return false | |
end | |
end | |
end | |
true | |
end | |
# usage | |
begin | |
port_open?('google.com', 80) | |
rescue Errno::ENETUNREACH, Errno::ECONNREFUSED | |
false | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment