#include <sys/socket.h>

ssize_t recvmsg(int <i>sockfd</i>, struct msghdr *<i>msg</i>, int <i>flags</i>);

ssize_t sendmsg(int <i>sockfd</i>, struct msghdr *<i>msg</i>, int <i>flags</i>);

<i>Обе функции возвращают: количество прочитанных или записанных байтов в случае успешного выполнения, -1 в случае ошибки</i>

Большинство аргументов обеих функций скрыто в структуре msghdr:

struct msghdr {

 void         *msg_name;     /* адрес протокола */

 socklen_t    msg_namelen;   /* размер адреса протокола */

 struct iovec *msg_iov;      /* массив буферов */

 size_t       msg_iovlen;    /* количество элементов в массиве msg_iov */

 void         *msg_control;  /* вспомогательные данные: должны быть

                                выровнены для структуры cmsghdr */

 socklen_t    msg_controllen; /* размер вспомогательных данных */

 int          msg_flags;      /* флаги, возвращенные функцией recvmsg() */

};

ПРИМЕЧАНИЕ

Показанная нами структура msghdr восходит к 4.3BSD Reno и определяется POSIX. Некоторые системы (например, Solaris 2.5) используют более раннюю структуру msghdr, которая появилась в 4.2BSD. У более ранней структуры нет элемента msg_flags, а элементы msg_control и msg_controllen называются msg_accrights и msg_accrightslen. В этой системе поддерживается только одна форма вспомогательных данных — передача дескрипторов файлов (так называемые права доступа). При появлении протоколов OSI в 4.3BSD Reno были добавлены новые формы вспомогательных данных, вследствие чего были обобщены имена элементов структуры.

Элементы msg_name и msg_namelen используются, когда сокет не является присоединенным (например, неприсоединенный сокет UDP). Они аналогичны пятому и шестому аргументам функций recvfrom и sendto: msg_name указывает на структуру адреса сокета, в которой вызывающий процесс хранит адрес протокола получателя для функции sendmsg или функция recvmsg хранит адрес протокола отправителя. Если нет необходимости задавать адрес протокола (например, сокет TCP или присоединенный сокет UDP), элемент msg _name должен быть пустым указателем. Элемент msg_namelen является аргументом типа «значение» для функции sendmsg, но для функции recvmsg это аргумент типа «значение-результат».

Элементы msg_iov и msg_iovlen задают массив буферов ввода и вывода (массив структур iovec), аналогичный второму и третьему аргументам функций readv и writev.

Элементы msg_control и msg_controllen задают расположение и размер необязательных вспомогательных данных. Элемент msg_controllen — это аргумент типа «значение-результат» функции recvmsg. Вспомогательные данные мы рассматриваем в разделе 14.6.

Работая с функциями recvmsg и sendmsg, следует учитывать различие между двумя флаговыми переменными: это аргумент flags, который передается по значению, и элемент msg_flags структуры msghdr, который передается по ссылке (поскольку функции передается адрес этой структуры).

■ Элемент msg_flags используется только функцией recvmsg. Когда вызывается функция recvmsg, аргумент flags копируется в элемент msg_flags [128, с. 502], и это значение используется ядром для управления приемом данных. Затем это значение обновляется в зависимости от результата функции recvmsg.

■ Элемент msg_flags игнорируется функцией sendmsg, поскольку эта функция использует аргумент flags для управления выводом данных. Это значит, что если мы хотим установить флаг MSG_DONTWAIT при вызове функции sendmsg, то мы должны присвоить это значение аргументу flags, а присваивание значения MSG_DONTWAIT элементу msg_flags не имеет никакого эффекта.

В табл. 14.2 показано, какие флаги проверяются ядром для функций ввода и вывода и какие элементы msg_flags может возвращать функция recvmsg. Для элемента sendmsg.msg_flags нет колонки, потому что, как мы отмечали, он не используется.

Таблица 14.2. Флаги для различных функций ввода-вывода

Флаг Проверяются функциями send flags sendto flags sendmsg flags Проверяются функциями recv flags recvfrom flags recvmsg flags Возвращаются функцией recvmsg msg_flags MSG_DONTROUTE • MSG_DONTWAIT • • MSG_PEEK • MSG_WAITALL • MSG_EOR • MSG_OOB • • • MSG_BCAST • MSG_MCAST • MSG_TRUNC • MSG_CTRUNC •

Перейти на страницу:
Изменить размер шрифта: