Created
August 30, 2012 03:40
-
-
Save jstorimer/3522068 to your computer and use it in GitHub Desktop.
Simple, parallel port scanner in Ruby built with connect_nonblock and IO.select.
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
require 'socket' | |
# Set up the parameters. | |
PORT_RANGE = 1..512 | |
HOST = 'archive.org' | |
TIME_TO_WAIT = 5 # seconds | |
# Create a socket for each port and initiate the nonblocking | |
# connect. | |
sockets = PORT_RANGE.map do |port| | |
socket = Socket.new(:INET, :STREAM) | |
remote_addr = Socket.sockaddr_in(port, HOST) | |
begin | |
socket.connect_nonblock(remote_addr) | |
rescue Errno::EINPROGRESS | |
# EINPROGRESS tells us that the connect cannot be completed immediately, | |
# but is continuing in the background. | |
end | |
socket | |
end | |
# Set the expiration. | |
expiration = Time.now + TIME_TO_WAIT | |
loop do | |
# We call IO.select and adjust the timeout each time so that we'll never | |
# be waiting past the expiration. | |
_, writable, _ = IO.select(nil, sockets, nil, expiration - Time.now) | |
break unless writable | |
writable.each do |socket| | |
begin | |
socket.connect_nonblock(socket.remote_address) | |
rescue Errno::EISCONN | |
# EISCONN tells us that the socket is already connected. Count this as a success. | |
puts "#{HOST}:#{socket.remote_address.ip_port} accepts connections..." | |
# Remove the socket from the array so it isn't selected multiple times. | |
sockets.delete(socket) | |
rescue Errno::EINVAL | |
sockets.delete(socket) | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment