Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding IO.select when reading socket in Ruby

Tags:

ruby

sockets

I have some code that I'm using to get data from a network socket. It works fine, but I flailed my way into it through trial and error. I humbly admit that I don't fully understand how it works, but I would really like to. (This was cargo culted form working code I found)

The part I don't understand starts with "ready = IO.select ..." I'm unclear on:

  1. What IO.select is doing (I tried looking it up but got even more confused with Kernel and what-not)
  2. what the array argument to IO.select is for
  3. what ready[0] is doing
  4. the general idea of reading 1024 bytes? at a time

Here's the code:

@mysocket = TCPSocket.new('192.168.1.1', 9761)

th = Thread.new do
    while true
        ready = IO.select([@mysocket])
        readable = ready[0]

        readable.each do |socket|
            if socket == @mysocket
                buf = @mysocket.recv_nonblock(1024)
                if buf.length == 0
                    puts "The server connection is dead. Exiting."
                    exit
                else
                    puts "Received a message"
                end
            end
        end

    end
end

Thanks in advance for helping me "learn to fish". I hate having bits of my code that I don't fully understand - it's just working by coincidence.

like image 490
Scott Avatar asked May 29 '11 03:05

Scott


1 Answers

1) IO.select takes a set of sockets and waits until it's possible to read or write with them (or if error happens). It returns sockets event happened with.

2) array contains sockets that are checked for events. In your case you specify only sockets for reading.

3) IO.select returns an array of arrays of sockets. Element 0 contains sockets you can read from, element 1 - sockets you can write to and element 2 - sockets with errors.

After getting list of sockets you can read the data.

4) yes, recv_nonblock argument is size in byte. Note that size of data actually being read may be less than 1024, in this case you may need to repeat select (if actual data matters for you).

like image 91
elder_george Avatar answered Oct 18 '22 23:10

elder_george