Читаем Linux API. Исчерпывающее руководство полностью

Если в потоковом сокете включить параметр TCP_CORK, то весь его вывод будет буферизироваться в одном TCP-сегменте, пока не произойдет одно из следующих событий: достижение максимального размера сегмента, выключение параметра TCP_CORK, закрытие сокета или завершение интервала в 200 миллисекунд с момента записи первого «закупоренного» байта. (Использование времени ожидания гарантирует, что данные будут переданы, даже если приложение забудет отключить TCP_CORK.)

Для включения и отключения параметра TCP_CORK служит системный вызов setsockopt() (см. раздел 57.9). Применение этого режима продемонстрировано на примере следующего кода, в котором реализован наш гипотетический HTTP-сервер (мы намеренно опустили проверку ошибок):

int optval;

/* Включаем TCP_CORK для 'sockfd' — последующий TCP-вывод закупоривается,

пока этот параметр не будет выключен. */

optval = 1;

setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, sizeof(optval));

write(sockfd…); /* Записываем HTTP-заголовки */

sendfile(sockfd…); /* Отправляем содержимое страницы */

/* Отключаем TCP_CORK для 'sockfd' — закупоренный вывод начинает

передаваться в виде единого TCP-сегмента. */

optval = 0

setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, sizeof(optval));

Мы могли бы избежать потенциальной передачи двух сегментов, создав в нашем приложении единый буфер данных, который можно было бы передавать с помощью одного вызова write(). (Как вариант, можно было бы воспользоваться вызовом writev(), чтобы объединить два разных буфера в одну групповую операцию.) Но если мы хотим выполнять передачу с нулевым копированием, которую обеспечивает вызов sendfile(), в сочетании с включением заголовка в первый сегмент передаваемого файла, то для этого нужно использовать параметр TCP_CORK.

В разделе 57.3 мы отмечали: флаг MSG_MORE обеспечивает похожее на TCP_CORK поведение, но для отдельных системных вызовов. Это не всегда является преимуществом. Мы можем включить для сокета параметр TCP_CORK и затем запустить программу, которая направляет вывод в унаследованный файловый дескриптор, не имея никакого представления о том, что использует данный параметр. Для сравнения, флаг MSG_MORE требует непосредственного изменения исходного кода программы.

В FreeBSD существует параметр, похожий на TCP_CORK; он называется TCP_NOPUSH.

57.5. Получение адреса сокета

Системные вызовы getsockname() и getpeername() возвращают локальный адрес, к которому привязан сокет, и, соответственно, адрес удаленного сокета на другом конце соединения.

#include

int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

Оба вызова возвращают 0 при успешном завершении или -1 при ошибке

В обоих вызовах аргумент sockfd обозначает файловый дескриптор, ссылающийся на сокет, а addr — указатель на буфер подходящего размера, применяемый для возвращения структуры с адресом сокета. Размер и тип этой структуры зависят от домена сокета. С помощью аргумента addrlen возвращается итоговый результат. Перед вызовом он должен быть равен размеру буфера, на который указывает addr; при возвращении он содержит количество байтов, записанных в этот буфер.

Функция getsockname() возвращает семейство адресов сокета и адрес, к которому привязан данный сокет. Это может пригодиться, если он был привязан другой программой (например, inetd(8)), а его файловый дескриптор был сохранен на протяжении работы вызова exec().

Функция getsockname() тоже может оказаться полезной, если мы хотим определить номер динамического порта, который был назначен ядром сокету интернет-домена во время его автоматической привязки. Ядро выполняет эту привязку в следующих случаях:

• после вызова connect() или listen() для TCP-сокета, который ранее не был привязан к адресу с помощью операции bind();

• при первом вызове sendto() для UDP-сокета, ранее не привязанного к адресу;

• после вызова bind(), если в качестве номера порта (sin_port) был указан 0. В этом случае данный вызов определяет IP-адрес сокета, а ядро выбирает для него номер динамического порта.

Системный вызов getpeername() возвращает адрес удаленного сокета на другом конце соединения. Это может пригодиться в ситуации, когда серверу нужно получить адрес клиента, инициировавшего соединение. Данную информацию можно также получить при выполнении вызова accept(); но если сервер был запущен программой, которая вызвала accept() (например, inetd), то не сможет получить сведения об адресе, несмотря на наличие файлового дескриптора сокета.

Использование функций getsockname() и getpeername() продемонстрировано в листинге 57.3. Эта программа задействует функции, которые мы определили в листинге 55.9, для выполнения следующих шагов.

Перейти на страницу:

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных
C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных