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

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

Шрифт:

int cmsg_level; /* исходящий протокол */

int cmsg_type; /* тип данных, специфичный для протокола */

/* далее следует массив символов без знака cmsg_data[] */

};

Мы уже видели эту структуру на рис. 14.2, когда она использовалась с параметром сокета

IP_RECVDSTADDR
для возвращения IP-адреса получателя полученной дейтаграммы UDP. Вспомогательные данные, на которые указывает элемент
msg_control
, должны быть соответствующим образом выровнены для структуры
cmsghdr
. Один из способов выравнивания мы показываем в листинге 15.7.

На рис. 14.3 приводится пример двух объектов вспомогательных данных, содержащихся в буфере управляющей информации.

Рис. 14.3. Два объекта вспомогательных данных

Элемент

msg_control
указывает на первый объект вспомогательных данных, а общая длина вспомогательных данных задается элементом
msg_controllen
. Каждому объекту предшествует структура
cmsghdr
, которая описывает объект. Между элементом
cmsg_type
и фактическими данными может существовать заполнение, а также заполнение может быть в конце данных, перед следующим объектом вспомогательных данных. Пять макросов
CMSG_xxx
, которые мы описываем далее, учитывают это возможное заполнение.

ПРИМЕЧАНИЕ

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

На рис. 14.4 приводится формат структуры

cmsghdr
при ее использовании с доменным сокетом Unix для передачи дескрипторов (см. раздел 15.7) или передачи данных, идентифицирующих пользователя (см. раздел 15.8).

Рис. 14.4. Структура cmsghdr при использовании с доменными сокетами Unix

Предполагается, что каждый из трех элементов структуры

cmsghdr
занимает 4 байта и между структурой
cmsghdr
и данными нет заполнения. При передаче дескрипторов содержимое массива
cmsg_data
— это фактические значения дескрипторов. На этом рисунке мы показываем только один передаваемый дескриптор, но в общем может передаваться и более одного дескриптора (тогда значение элемента
cmsg_len
будет равно 12 плюс число дескрипторов, умноженное на 4, если считать, что каждый дескриптор занимает 4 байта).

Вспомогательные данные, возвращаемые функцией

recvmsg
, могут содержать любое число объектов вспомогательных данных. Чтобы скрыть возможное заполнение от приложения, для упрощения обработки вспомогательных данных определены следующие пять макросов (что требует включения заголовочного файла
<sys/socket.h>
).

#include <sys/socket.h>

#include <sys/param.h> /* для макроса ALIGN во многих реализациях */

struct cmsghdr *CMSG_FIRSTHDR(struct msghdr * mhdrptr);

Возвращает: указатель на первую структуру cmsghdr или NULL, если нет вспомогательных данных

struct cmsghdr *CMSG_NXTHDR(struct msghdr * mhdrptr, struct cmsghdr * cmsgptr);

Возвращает: указатель на структуру cmsghdr или NULL, если нет больше объектов вспомогательных данных

unsigned char *CMSG_DATA(struct cmsghdr * cmsgptr);

Возвращает: указатель на первый байт данных, связанных со структурой cmsghdr

unsigned int CMSG_LEN(unsigned int length);

Возвращает: значение, которое записывается в cmsg_len

unsigned int CMSG_SPACE(unsigned int length);

Возвращает: общий размер объекта вспомогательных данных

ПРИМЕЧАНИЕ

В POSIX определены первые пять макросов, а в [113] определены последние два.

Эти макросы могли бы быть использованы в следующем псевдокоде:

struct msghdr msg;

struct cmsghdr *cmsgptr;

/* заполнение структуры msg */

/* вызов recvmsg */

for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;

  • Читать дальше
  • 1
  • ...
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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