Что такое IO.select при чтении сокета в Ruby

У меня есть код, который я использую для получения данных из сетевого сокета. Он работает нормально, но я пробился к нему методом проб и ошибок. Я смиренно признаю, что не совсем понимаю, как это работает, но мне бы очень хотелось. (Это был рабочий код, созданный из загруженной формы, который я нашел)

Часть, которую я не понимаю, начинается с "ready = IO.select ...". Я не понимаю:

  1. Что делает IO.select (я попытался найти его, но еще больше запутался с ядром и чем-то еще)
  2. какой аргумент массива для IO.select предназначен для
  3. что ready [0] делает
  4. общую идею чтения 1024 байтов? за раз

Вот код:

@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

Заранее спасибо за то, что помог мне «научиться ловить рыбу». Я ненавижу фрагменты моего кода, которые я не понимаю полностью - они работают случайно.

18
задан Scott 29 May 2011 в 03:14
поделиться

1 ответ

1) IO.select берет набор сокетов и ждет, пока можно будет читать или писать с ними (или если произойдет ошибка). Возвращает событие сокетов, которое произошло с.

2) массив содержит сокеты, которые проверяются на наличие событий. В вашем случае вы указываете только сокеты для чтения.

3) IO.select возвращает массив массивов сокетов. Элемент 0 содержит сокеты, из которых вы можете читать, элемент 1 - сокеты, в которые вы можете писать, и элемент 2 - сокеты с ошибками.

После получения списка сокетов вы можете прочитать данные.

4) да, recv_nonblock аргумент - это размер в байтах. Обратите внимание, что размер фактически читаемых данных может быть меньше 1024, в этом случае вам может потребоваться повторить select (если для вас важны фактические данные).

22
ответ дан 30 November 2019 в 08:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: