Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:
Настройка структур kevent для kqueue

12-13
При помощи макроса
EV_SET
мы настраиваем две структуры
kevent
. Обе содержат фильтр событий готовности к чтению (
EVFILT_READ
) и запрос на добавление этого события к фильтру (
EV_ADD
).

Создание kqueue и добавление фильтров

14-16
Мы вызываем
kqueue
, чтобы получить дескриптор
kqueue
, устанавливаем тайм- аут равным нулю, чтобы сделать вызов
kevent
неблокируемым, и наконец, вызываем
kevent
с массивом
kevent
на месте соответствующего аргумента.

Бесконечный цикл с блокированием в kevent

17-18
Мы входим в бесконечный цикл и блокируемся в
kevent
. Функции передается пустой список изменений, потому что все интересующие нас события уже зарегистрированы, и нулевой тайм-аут, что позволяет заблокироваться навечно.

Перебор возвращаемых событий в цикле

19
Мы проверяем все возвращаемые события и обрабатываем их последовательно.

Сокет готов для чтения

20-28
Эта часть кода ничем не отличается от листинга 6.2.

Вход готов для чтения

29-40
Код практически аналогичен листингу 6.2 за тем отличием, что нам приходится обрабатывать конец файла, возвращаемый
kqueue
. Для каналов и терминалов
kqueue
возвращает событие готовности дескриптора к чтению, подобно
select
, так что мы можем считать из этого дескриптора символ конца файла. Для файлов
kqueue
возвращает количество байтов, оставшихся в поле
data
структуры
struct kevent
и предполагает, что приложение само определит, когда оно доберется до конца этих данных. Поэтому мы переписываем цикл таким образом, чтобы отправлять данные по сети, если они были считаны из дескриптора. Затем проверяется достижение конца файла: если мы считали нуль байтов или если мы считали все оставшиеся байты из дескриптора файла, значит, это и есть
EOF
. Еще одно изменение состоит в том, что вместо
FD_CLR
для удаления дескриптора из набора файлов мы используем флаг
EV_DELETE
и вызываем
kevent
для удаления события из фильтра в ядре.

Рекомендации

Новыми интерфейсами следует пользоваться аккуратно. Читайте свежую документацию, относящуюся к конкретному выпуску операционной системы. Интерфейсы часто меняются от одного выпуска к другому, причем таким образом, что заметно это далеко не сразу. Все это продолжается до тех пор, пока поставщики не проработают все детали функционирования новых интерфейсов.

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

14.10. Резюме

Существует три способа установить ограничение времени для операции с сокетом:

Использовать функцию

alarm
и сигнал
SIGALRM
.

Задать предел времени в функции

select
.

Использовать более новые параметры сокета

SO_RCVTIMEO
и
SO_SNDTIMEO
.

Первый способ легко использовать, но он включает обработку сигналов и, как показано в разделе 20.5, может привести к ситуации гонок. Использование функции

select
означает, что блокирование происходит в этой функции (с заданным в ней пределом времени) вместо блокирования в вызове функции
read
,
write
или
connect
. Другая альтернатива — использование новых параметров сокета — также проста в использовании, но предоставляется не всеми реализациями.

Функции

recvmsg
и
sendmsg
являются наиболее общими из пяти групп предоставляемых функций ввода-вывода. Они объединяют целый ряд возможностей, свойственных других функциям ввода-вывода, позволяя задавать флаг
MSG_xxx
(как функции
recv
и
send
), возвращать или задавать адрес протокола собеседника (как функции
recvfrom
и
sendto
), использовать множество буферов (как функции
readv
и
writev
). Кроме того, они обеспечивают две новых возможности: возвращение флагов приложению и получение или отправку вспомогательных данных.

В тексте книги мы описываем десять различных форм вспомогательных данных, шесть из которых появились в IPv6. Вспомогательные данные состоят из объектов вспомогательных данных. Перед каждым объектом идет структура

cmsghdr
, задающая его длину, уровень протокола и тип данных. Пять макросов, начинающихся с префикса
CMSG_
, используются для создания и анализа вспомогательных данных.

Сокеты могут использоваться со стандартной библиотекой ввода-вывода С, но это добавляет еще один уровень буферизации к уже имеющемуся в TCP. На самом деле недостаток понимания буферизации, выполняемой стандартной библиотекой ввода-вывода, является наиболее общей проблемой при работе с этой библиотекой. Поскольку сокет не является терминальным устройством, общим решением этой потенциальной проблемы будет отключение буферизации стандартного потока ввода-вывода.

Многие производители предоставляют усовершенствованные средства опроса событий без накладных расходов на

select
и
poll
. Не стоит увлекаться написанием непереносимого кода, однако иногда преимущества перевешивают риск непереносимости.

Упражнения

1. Что происходит в листинге 14.1, когда мы переустанавливаем обработчик сигналов, если процесс не установил обработчик для сигнала

SIGALRM
?

2. В листинге 14.1 мы выводим предупреждение, если у процесса уже установлен таймер

alarm
. Измените эту функцию так, чтобы новое значение
alarm
для процесса задавалось после выполнения connect до завершения функции.

  • Читать дальше
  • 1
  • ...
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: