Пока значение минимального количества данных для отправки в сокете UDP меньше, чем буфер отправки сокета (а такое отношение между ними всегда устанавливается по умолчанию), сокет UDP всегда готов для записи, поскольку соединения не требуется.
В табл. 6.1 суммируются описанные выше условия, при которых сокет становится готовым для вызова функции select
.
Таблица 6.1. Условия, при которых функция select сообщает, что сокет готов для чтения или для записи либо, что необходима обработка исключительной ситуации
Условие |
Сокет готов для чтения |
Сокет готов для записи |
Исключительная ситуация |
Данные для чтения |
• |
|
|
Считывающая половина соединения закрыта |
• |
|
|
Для прослушиваемого сокета готово новое соединение |
• |
|
|
Пространство, доступное для записи |
|
• |
|
Записывающая половина соединения закрыта |
|
• |
|
Ошибка, ожидающая обработки |
• |
• |
|
Внеполосные данные TCP |
|
|
• |
Максимальное число дескрипторов для функции select
Ранее мы сказали, что большинство приложений не используют много дескрипторов. Например, редко можно найти приложение, использующее сотни дескрипторов. Но такие приложения существуют, и часто они используют функцию select
для мультиплексирования дескрипторов. Когда функция select
была создана, операционные системы обычно имели ограничение на максимальное число дескрипторов для каждого процесса (этот предел в реализации 4.2BSD составлял 31), и функция select
просто использовала тот же предел. Но современные версии Unix допускают неограниченное число дескрипторов для каждого процесса (часто оно ограничивается только количеством памяти и административными правилами), поэтому возникает вопрос: как же теперь работает функция select
?
Многие реализации имеют объявления, аналогичные приведенному ниже, которое взято из заголовочного файла 4.4BSD :
/*
Значение FD_SETSIZE может быть определено пользователем,
но заданное здесь по умолчанию
является достаточным в большинстве случаев.
*/
#ifndef FD_SETSIZE
#define FD_SETSIZE 256
#endif
Исходя из этого комментария, можно подумать, что если перед подключением этого заголовочного файла присвоить FD_SETSIZE
значение, превышающее 256, то увеличится размер наборов дескрипторов, используемых функцией select
. К сожалению, обычно это не действует.
ПРИМЕЧАНИЕ
Чтобы понять, в чем дело, обратите внимание, что на рис. 16.53 [128] объявляются три набора дескрипторов внутри ядра, а в качестве верхнего предела используется определенное в ядре значение FD_SETSIZE. Единственный способ увеличить размер наборов дескрипторов — это увеличить значение FD_SETSIZE и затем перекомпилировать ядро. Изменения значения без перекомпиляции ядра недостаточно.
Некоторые производители изменяют свои реализации функции select
, с тем чтобы позволить процессу задавать значение FD_SETSIZE
, превышающее значение по умолчанию. BSD/OS также изменила реализацию ядра, чтобы допустить большие наборы дескрипторов, кроме того, в ней добавлено четыре новых макроопределения FD_ xxx
для динамического размещения больших наборов дескрипторов в памяти и для работы с ними. Однако с точки зрения переносимости не стоит злоупотреблять использованием больших наборов дескрипторов.
6.4. Функция str_cli (продолжение)
Теперь мы можем переписать нашу функцию str_cli
, представленную в разделе 5.5 (на этот раз используя функцию select
), таким образом, чтобы мы получали уведомление, как только завершится процесс сервера. Проблема с предыдущей версией состояла в том, что процесс мог оказаться заблокированным в вызове функции fgets
, когда что-то происходило на сокете. Наша новая версия этой функции вместо этого блокируется в вызове функции select
, ожидая готовности для чтения либо стандартного потока ввода, либо сокета. На рис. 6.7 показаны различные условия, обрабатываемые с помощью вызова функции select
.
Рис. 6.7. Условия, обрабатываемые функцией select в вызове функции str_cli
Сокет обрабатывает три условия:
1. Если протокол TCP собеседника отправляет данные, сокет становится готовым для чтения, и функция read
возвращает положительное значение (то есть число байтов данных).
Читать дальше
Конец ознакомительного отрывка
Купить книгу