Читаем UNIX: разработка сетевых приложений полностью

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].

<p>7.12. Резюме</p></span><span>

Параметры сокетов лежат в широком диапазоне от очень общих (SO_ERROR) до очень специфических (параметры заголовка IP). Наиболее общеупотребительные параметры сокетов, которые нам могут встретиться, — это SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF и SO_REUSEADDR. Последний должен всегда задаваться для сервера TCP до того, как сервер вызовет функцию bind (см. листинг 11.6). Параметр SO_BROADCAST и десять параметров сокетов многоадресной передачи предназначены только для приложений, передающих соответственно широковещательные или многоадресные сообщения.

Параметр сокета SO_KEEPALIVE устанавливается многими серверами TCP и автоматически закрывает наполовину открытое соединение. Замечательное свойство этого параметра в том, что он обрабатывается на уровне TCP, не требуя на уровне приложения наличия таймера, измеряющего период отсутствия активности. Однако недостаток этого параметра в том, что он не видит разницы между выходом собеседника из строя и временной потерей соединения с ним. SCTP предоставляет 17 параметров сокетов, с помощью которых приложение может управлять транспортным уровнем. SCTP_NODELAY и SCTP_MAXSEG аналогичны TCP_NODELAY и TCP_MAXSEG, и выполняют схожие функции. Остальные 17 параметров позволяют приложению более точно контролировать поведение стека SCTP. Большинство этих параметров будет рассмотрено в главе 23.

Параметр сокета SO_LINGER расширяет наши возможности в отношении контроля над функцией close — мы можем отложить ее завершение на некоторое время. Кроме того, этот параметр позволяет нам отправить сегмент RST вместо обычной последовательности из четырех пакетов, завершающих соединение TCP. Следует соблюдать осторожность при отправке сегментов RST, поскольку в этом случае не наступает состояние TCP TIME_WAIT. Бывает, что этот параметр сокета не обеспечивает необходимой нам информации, и тогда требуется реализовать подтверждение на уровне приложения.

У каждого сокета TCP имеется буфер отправки и буфер приема, а у каждого сокета UDP есть буфер приема. Параметры сокета SO_SNDBUF и SO_RCVBUF позволяют нам изменять размеры этих буферов. Основное применение эти функции находят при передаче большого количества данных по каналам с повышенной пропускной способностью, которые представляют собой соединения TCP либо с широкой полосой пропускания, либо с большой задержкой, часто с использованием расширений из RFC 1323. Сокеты UDP, наоборот, могут стремиться увеличить размер приемного буфера, чтобы позволить ядру установить в очередь больше дейтаграмм, если приложение занято.

<p>Упражнения</p></span><span>
Перейти на страницу:

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

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

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги