July 14, 2006

Goofing with TCPSocket & Kernel.select in Ruby on Mac

I wanted to quickly check something with the following code:

port_start = 8000
port_count = 100
port_end   = port_start + port_count
listeners = []
connected = []

port_start.upto(port_end) do |port|
  listeners << TCPServer.new('localhost', port) 
end

loop do
  select_set = Kernel.select(listeners+connected,nil,nil,2.5)
  puts "returned from select: #{select_set}"
end

I fired up the script, then fired up trusty netcat:

echo "Bob" | nc localhost 8000

Hmm, nothing happened..... I check netstat -na

Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
tcp6       0      0  ::1.8100               *.*                    LISTEN
tcp6       0      0  ::1.8099               *.*                    LISTEN
tcp6       0      0  ::1.8098               *.*                    LISTEN
.....

I didn't realize that 'localhost' in my Ruby code would cause IPv6 bindings, yet nc using 'localhost' would attempt an IPv4 connection. Interesting. The problem is quickly fixed by using '127.0.0.1' directly in the Ruby code.

Posted by cbrown at July 14, 2006 9:31 AM