Уильям Стивенс - UNIX: разработка сетевых приложений
- Название:UNIX: разработка сетевых приложений
- Автор:
- Жанр:
- Издательство:Питер
- Год:2007
- Город:Санкт-Петербург
- ISBN:5-94723-991-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
7.11. Функция fcntl
Сокращение fcntl
означает «управление файлами» (file control). Эта функция выполняет различные операции управления дескрипторами. Перед описанием этой функции и ее влияния на сокет нам нужно составить некоторое более общее представление о ее возможностях. В табл. 7.9 приводятся различные операции, выполняемые функциями fcntl
и ioctl
и маршрутизирующими сокетами.
Таблица 7.9. Операции функций fcntl и ioctl и маршрутизирующих сокетов
Операция | fcntl | ioctl | Маршрутизирующий сокет | Posix.1g |
---|---|---|---|---|
Установка сокета для неблокируемого ввода-вывода | F_SETFL, O_NONBLOCK | FIONBIO | fcntl | |
Установка сокета для ввода-вывода, управляемого сигналом | F_SETFL, O_ASYNC | FIOASYNC | fcntl | |
Установка владельца сокета | F_SETOWN | SIOCSPGRP или FIOSETOWN | fcntl | |
Получение владельца сокета | F_GETOWN | SIOCGPGRP или FIOGETOWN | fcntl | |
Получение текущего количества байтов в приемном буфере сокета | FIONREAD | |||
Проверка, находится ли процесс на отметке внеполосных данных | SIOCATMARK | sockatmark | ||
Получение списка интерфейсов | SIOCGIFCONF | Sysctl | ||
Операции интерфейсов | SIOC[GS]IF xxx | |||
Кэш-операции ARP | SIOC x ARP | RTM_ xxx | ||
Операции таблицы маршрутизации | SIOG xxx RT | RTM_ xxx |
Первые шесть операций могут применяться к сокетам любым процессом, следующие две (операции над интерфейсами) используются реже, а последние две (ARP и таблица маршрутизации) выполняются администрирующими программами, такими как ifconfig
и route
. О различных операциях функции ioctl
мы поговорим подробнее в главе 17, а о маршрутизирующих сокетах — в главе 18.
Существует множество способов выполнения первых четырех операций, но, как указано в последней колонке, стандарт POSIX определяет, что функция fcntl
является предпочтительным способом. Отметим также, что POSIX предлагает функцию sockatmark
(см. раздел 24.3) как наиболее предпочтительный способ тестирования на предмет пребывания процесса на отметке внеполосных данных. Оставшиеся операции с пустой последней колонкой не стандартизованы POSIX.
Отметим также, что первые две операции, устанавливающие сокет для неблокируемого ввода-вывода и для ввода-вывода, управляемого сигналом, традиционно применялись с использованием команд FNDELAY и FASYNC функции fcntl. POSIX определяет константы О_ xxx .
Функция fcntl
предоставляет следующие возможности, относящиеся к сетевому программированию:
■ Неблокируемый ввод-вывод. Мы можем установить флаг состояния файла O_NONBLOCK
, используя команду F_SETFL
для отключения блокировки сокета. Неблокируемый ввод-вывод мы описываем в главе 16.
■ Управляемый сигналом ввод-вывод. Мы можем установить флаг состояния файла O_ASYNC
, используя команду F_SETFL
, после чего при изменении состояния сокета будет генерироваться сигнал SIGIO. Мы рассмотрим это в главе 25.
■ Команда F_SETOWN
позволяет нам установить владельца сокета (идентификатор процесса или идентификатор группы процессов), который будет получать сигналы SIGIO
и SIGURG
. Первый сигнал генерируется, если для сокета включен управляемый сигналом ввод-вывод (см. главу 25), второй — когда для сокета приходят новые внеполосные (out-of-band data) данные (см. главу 24). Команда F_GETOWN
возвращает текущего владельца сокета.
Термин «владелец сокета» определяется POSIX. Исторически реализации, происходящие от Беркли, называли его «идентификатор группы процессов сокета», потому что переменная, хранящая этот идентификатор, — это элемент so_pgid структуры socket [128, с. 438].
#include
int fcntl(int fd , int cmd , ... /* int arg */);
Возвращает: в случае успешного выполнения результат зависит от аргумента cmd, -1 в случае ошибки
Каждый дескриптор (включая сокет) имеет набор флагов, которые можно получить с помощью команды F_GETFL
и установить с помощью команды F_SETFL
. На сокет влияют следующие два флага:
■ O_NONBLOCK
— неблокируемый ввод-вывод;
■ O_ASYNC
— ввод-вывод, управляемый сигналом.
Позже мы опишем оба эти флага подробнее. Отметим, что типичный код, который устанавливает неблокируемый ввод-вывод с использованием функции fcntl
, выглядит следующим образом:
int flags;
/* Делаем сокет неблокируемым */
if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
err_sys("F_GETFL error");
flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0)
err_sys("F_SETFL error");
Учтите, что вам может встретиться код, который просто устанавливает желаемый флаг:
/* Неправильный способ сделать сокет неблокируемым */
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
err_sys("F_SETFL error");
Хотя при этом и устанавливается флаг отключения блокировки, также снимаются все остальные флаги состояния файла. Единственный корректный способ установить один из этих флагов состояния файла — получить текущие флаги, с помощью операции логического ИЛИ добавить новый флаг, а затем установить флаги.
Следующий код сбрасывает флаг отключения блокировки в предположении, что переменная flags
была задана с помощью вызова функции fcntl
, показанного ранее:
flags &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0)
err_sys("F_SETFL error");
Сигналы SIGIO
и SIGURG
отличаются от других тем, что они генерируются для сокета, только если сокету был присвоен владелец с помощью команды F_SETOWN
. Целое значение аргумента arg
для команды F_SETOWN
может быть либо положительным, задающим идентификатор процесса, получающего сигнал, либо отрицательным, абсолютное значение которого — это идентификатор группы процессов, получающей сигнал. Команда F_GETOWN
возвращает владельца сокета, так как возвращаемое значение функции fcntl
— либо идентификатор процесса (положительное возвращаемое значение), либо идентификатор группы процессов (отрицательное значение, отличное от -1). Разница между заданием процесса и группы процессов, получающих сигнал, в том, что в первом случае сигнал будет получен только одиночным процессом, тогда как во втором случае его получают все процессы в группе.
Когда создается новый сокет с помощью функции socket, у него нет владельца. Сокет, создаваемый из прослушиваемого сокета, наследует от него принадлежность владельцу (как и многие другие параметры сокетов [128, с. 462-463].
7.12. Резюме
Параметры сокетов лежат в широком диапазоне от очень общих ( SO_ERROR
) до очень специфических (параметры заголовка IP). Наиболее общеупотребительные параметры сокетов, которые нам могут встретиться, — это SO_KEEPALIVE
, SO_RCVBUF
, SO_SNDBUF
и SO_REUSEADDR
. Последний должен всегда задаваться для сервера TCP до того, как сервер вызовет функцию bind
(см. листинг 11.6). Параметр SO_BROADCAST
и десять параметров сокетов многоадресной передачи предназначены только для приложений, передающих соответственно широковещательные или многоадресные сообщения.
Интервал:
Закладка: