Unix Sockets: select () с более чем одним связанным набором делает больше, чем должно - PullRequest
0 голосов
/ 21 июня 2011

У меня следующий вызов select для tcp сокетов:

ret = select(nfds + 1, &rfds, &rfds2, NULL, &tv);

rfds2 используется при отправке больших данных (неблокирующий режим).И rfds обнаруживает, получили ли мы что-то в сокете.

Теперь, когда буфер отправки пуст, я обнаруживаю это с помощью rfds2.Но в то же время я получаю сокет обратно в rfds, хотя я ничего не получил по этому сокету.

Это предполагаемое поведение вызова select?Как правильно различить отправляющий и получающий дела?

Ответы [ 3 ]

1 голос
/ 21 июня 2011

Теперь, когда буфер отправки пуст, я обнаруживаю его с помощью rfds2

Это не правильно.select () обнаружит, когда в буфере отправки есть место. Вряд ли когда-либо правильно зарегистрировать сокет для OP_READ и OP_WRITE одновременно.OP_WRITE почти всегда готов, за исключением коротких интервалов, когда буфер отправки заполнен .

1 голос
/ 21 июня 2011

Спасибо за ваши ответы. Я нашел проблему для себя: Неисправный код был после вызова select (как я использовал FD_ISSET(), чтобы определить, какое действие я могу сделать).

Я думаю, что мое предположение верно, что в rfds есть только сокет, когда действительно есть данные, которые можно получить.

0 голосов
/ 21 июня 2011

Если сокет не является блокирующим, это похоже на ожидаемое поведение.Страница справочника для select имеет следующее: аргумент readfds:

Перечисленные в readfds будут отслеживаться, чтобы увидеть, станут ли символы доступными для чтения (точнее, посмотреть, не заблокирует ли чтение чтение).; в частности, файловый дескриптор также готов к концу файла)

Поскольку сокет не является блокирующим, верно, что чтение не будет блокировать, и, следовательно, разумно для этого битабыть установленным.

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

Как правило,thumb, всякий раз, когда select возвращает, вы должны обрабатывать каждый сокет, который он указывает, готов, либо считывая и обрабатывая любые доступные данные, если он возвращается как готовый к чтению, или записывая больше данных, если он возвращается как готовый к записи.Вы не должны предполагать, что при каждом возврате будет сигнализироваться только одно событие.

...