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-2025 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |