У меня есть код, который я использую для получения данных из сетевого сокета. Он работает нормально, но я пробился к нему методом проб и ошибок. Я смиренно признаю, что не совсем понимаю, как это работает, но мне бы очень хотелось. (Это был рабочий код, созданный из загруженной формы, который я нашел)
Часть, которую я не понимаю, начинается с "ready = IO.select ...". Я не понимаю:
Вот код:
@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
Заранее спасибо за то, что помог мне «научиться ловить рыбу». Я ненавижу фрагменты моего кода, которые я не понимаю полностью - они работают случайно.
1) IO.select
берет набор сокетов и ждет, пока можно будет читать или писать с ними (или если произойдет ошибка). Возвращает событие сокетов, которое произошло с.
2) массив содержит сокеты, которые проверяются на наличие событий. В вашем случае вы указываете только сокеты для чтения.
3) IO.select
возвращает массив массивов сокетов. Элемент 0 содержит сокеты, из которых вы можете читать, элемент 1 - сокеты, в которые вы можете писать, и элемент 2 - сокеты с ошибками.
После получения списка сокетов вы можете прочитать данные.
4) да, recv_nonblock
аргумент - это размер в байтах. Обратите внимание, что размер фактически читаемых данных может быть меньше 1024, в этом случае вам может потребоваться повторить select
(если для вас важны фактические данные).