выберите (), recv () и EWOULDBLOCK при неблокировании сокетов

Я думаю, что большинство людей считают что-то вроде

isPrimaryColor = ["Red", "Blue", "Yellow"].contains(someColor)

достаточно ясным, что им не нужен дополнительный синтаксис для этого.

9
задан mrvincenzo 23 August 2009 в 11:10
поделиться

7 ответов

Мне известно об ошибке в популярной операционной системе рабочего стола, когда сокеты TCP O_NONBLOCK , особенно те, которые работают через интерфейс обратной связи, иногда могут возвращать EAGAIN из recv () после select () сообщает, что сокет готов к чтению. В моем случае это происходит после того, как другая сторона наполовину закрывает поток отправки.

Для получения дополнительных сведений см. Исходный код t_nx.ml в библиотеке NX моего дистрибутива OCaml Network Application Environment. ( ссылка )

3
ответ дан 4 December 2019 в 13:49
поделиться

Для recv () вы получите EAGAIN вместо EWOULDBLOCK , и да, это возможно. Поскольку вы только что проверили с помощью select () , произошло одно из двух:

  • Что-то еще (другой поток) опустошило входной буфер между select () и recv () .
  • Для сокета был установлен тайм-аут приема, и он истек без получения данных.
5
ответ дан 4 December 2019 в 13:49
поделиться

Это возможно, но только в ситуации, когда несколько потоков / процессов пытаются читать из одного и того же сокета.

3
ответ дан 4 December 2019 в 13:49
поделиться

Если вы не вызовете какой-либо другой системный вызов между select () и recv () на этом сокете, то recv () никогда не вернет EAGAIN или EWOULDBLOCK.

Я не знаю, что они означают с таймаутом recv, однако стандарт POSIX не упоминает об этом здесь, поэтому вы можете быть в безопасности, вызывая recv ().

-1
ответ дан 4 December 2019 в 13:49
поделиться

Это возможно в многопоточной среде, где два потока читают из сокета. Это многопоточное приложение?

0
ответ дан 4 December 2019 в 13:49
поделиться

Хотя мое приложение является однопоточным, я заметил, что описанное поведение не является редкостью в RHEL5. Оба с сокетами TCP и UDP, для которых было установлено значение O_NONBLOCK (единственный установленный параметр сокета). select () сообщает, что сокет готов, но следующий recv () возвращает EAGAIN.

1
ответ дан 4 December 2019 в 13:49
поделиться

В Linux даже задокументировано, что это может произойти, как я его читал.

См. Этот вопрос:

Уведомление о ложной готовности для системного вызова Select

3
ответ дан 4 December 2019 в 13:49
поделиться