struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh, struct cmsghdr *cmsg);
size_t CMSG_ALIGN(size_t length);
size_t CMSG_SPACE(size_t length);
size_t CMSG_LEN(size_t length);
unsigned char *CMSG_DATA(struct cmsghdr *cmsg);
struct cmsghdr { socklen_t cmsg_len; /* счетчик байтов данных с заголовком */ int cmsg_level; /* создаваемый протокол передачи */ int cmsg_type; /* тип, зависящий от протокола */ /* с последующей переменной без знакаcmsg_data[]; */ };
Служебные данные являются последовательностью структур struct cmsghdr с присоединенными к ней данными. Доступ к этой последовательности может быть осуществлен только с помощью макросов, описанных в данном руководстве. Смотрите также соответствующие страницы руководства, описывающие протоколы для получения полной информации о доступных типах управляюший сообщений. Максимально возможный размер буфера в одном пакете можно установить, используя системный вызов (sysctl) net.core.optmem_max; см. также socket(7).
CMSG_FIRSTHDR возвращает указатель на первый cmsghdr в буфере служебных данных, связанных с переданным msghdr.
CMSG_NXTHDR возвращает следующее значение cmsghdr после переданного cmsghdr. Он возвращает NULL, если в буфере недостаточно места.
CMSG_ALIGN возвращает длину и необходимые выравнивания. Это постоянное выражение.
CMSG_SPACE возвращает объем в байтах, который занимают управляющие элементы и полезная "нагрузка" переданных данных. Это постоянное выражение.
CMSG_DATA возвращает указатель на часть данных в cmsghdr.
CMSG_LEN возвращает величину, содержащуюся в элементе cmsg_len структуры cmsghdr с учетом необходимых выравниваний; он принимает значение длины данных в качестве аргумента. Это постоянное выражение.
Чтобы создать служебные данные, сначала инициализируйте элемент msg_controllen структуры msghdr , указав длину буфера управляющего сообщения. Используйте CMSG_FIRSTHDR в структуре msghdr для получения первого контрольного сообщения и CMSG_NEXTHDR для получения последующих. Для каждого управляющего сообщения инициализируется cmsg_len (с помощью CMSG_LEN) и другие поля заголовка cmsghdr , а также часть данных (с помощью CMSG_DATA). По окончании операции значение поля msg_controllen структуры msghdr должно быть установлено равным сумме величин CMSG_SPACE (это должно быть справедливо для длин всех управляющих сообщений в буфере). Дополнительная информация о msghdr находится в recvmsg(2).
Если буфер управляющих сообщений слишком мал для сохранения всех сообщений, то флаг MSG_CTRUNC в поле msg_flags структуры msghdr присваивает значение, равное единице.
struct msghdr msgh; struct cmsghdr *cmsg; int *ttlptr; int received_ttl; /* Принять служебные данные в msgh */ for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg) { if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) { ttlptr = (int *) CMSG_DATA(cmsg); received_ttl = *ttlptr; break; } } if (cmsg == NULL) { /* Ошибка: IP_TTL не разрешен, недостаточно размера буфера, * или произошла ошибка ввода-вывода. */ }
Эта часть программы передает массив файловых описателей через сокет Unix, используя SCM_RIGHTS:
struct msghdr msg = {0}; struct cmsghdr *cmsg; int myfds[NUM_FD]; /* Содержит описатели файлов для передачи. */ char buf[CMSG_SPACE(sizeof myfds)]; /* буфер служебных данных */ int *fdptr; msg.msg_control = buf; msg.msg_controllen = sizeof buf; cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD); /* Инициализация полезных данных: */ fdptr = (int *)CMSG_DATA(cmsg); memcpy(fdptr, myfds, NUM_FD * sizeof(int)); /* Сумма длин всех управляющих сообщений в буфере: */ msg.msg_controllen = cmsg->cmsg_len;
В Linux CMSG_LEN, CMSG_DATA и CMSG_ALIGN - это постоянные выражения (вне зависимости от переданных аргументов). Вы можете воспользоваться этим свойством для объявления размеров глобальных переменных. Но это также сделает программу непереносимой на другие платформы.
RFC 2292
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |