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:
- What IO.select is doing (I tried looking it up but got even more confused with Kernel and what-not)
- what the array argument to IO.select is for
- what ready[0] is doing
- 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.
1)
IO.selecttakes 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.selectreturns 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_nonblockargument is size in byte. Note that size of data actually being read may be less than 1024, in this case you may need to repeatselect(if actual data matters for you).