#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 | | | • |