ИМЯ

sendmmsg - отправляет несколько сообщений в сокет

LIBRARY

Standard C library ( libc, -lc)

СИНТАКСИС

#define _GNU_SOURCE         /* Смотрите feature_test_macros(7) */
#include <sys/socket.h>
int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen,
             int flags);

ОПИСАНИЕ

Системный вызов sendmmsg() является расширенной версией sendmsg(2), позволяя вызывающему передавать несколько сообщений из сокета, используя только один системный вызов (в некоторых приложениях это позволяет получить выигрыш в производительности).
Аргумент sockfd представляет собой файловый дескриптор сокета для отправки данных.
Аргумент msgvec является указателем на массив структур mmsghdr. Размер этого массива указывается в vlen.
Структура mmsghdr определена в <sys/socket.h> следующим образом:

struct mmsghdr {
    struct msghdr msg_hdr;  /* заголовок сообщения */
    unsigned int  msg_len;  /* кол-во переданных байт */
};

Поле msg_hdr представляет собой структуру msghdr, которая описана в sendmsg(2). Поле msg_len используется для возврата количества байт, посланных из сообщения в msg_hdr (т. е., такое же значение, что и возвращаемое значение одиночного вызова sendmsg(2)).
Аргумент flags содержит объединённые с помощью OR флаги. Флаги те же, что и у sendmsg(2).
Блокирование вызова sendmmsg() происходит до тех пор, пока не будет отправлено vlen сообщений. Неблокирующий вызов посылает столько сообщений сколько возможно (максимальное количество указано в vlen) и сразу завершает работу.
При возврате из sendmmsg(), поля msg_len последующих элементов msgvec обновляются и содержат количество байт, переданных из соответствующего msg_hdr. Возвращаемое вызовом значение равно количеству элементов msgvec, которые были обновлены.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении sendmmsg() возвращает количество сообщений, посланных из msgvec; если это значение меньше чем vlen, то вызывающий может повторить вызов sendmmsg() для отправки оставшихся сообщений.
В случае ошибки возвращается -1, а errno устанавливается в значение ошибки.

ОШИБКИ

Возникают те же ошибки что и для sendmsg(2). Ошибка возвращается только, если ни одной дейтаграммы не послано. Смотрите также ДЕФЕКТЫ.

ВЕРСИИ

The sendmmsg() system call was added in Linux 3.0. Support in glibc was added in Linux 2.14.

СТАНДАРТЫ

Вызов sendmmsg() есть только в Linux.

ЗАМЕЧАНИЯ

Значение, указанное в vlen, ограничено UIO_MAXIOV (1024).

ДЕФЕКТЫ

Если после отправки хотя бы одного сообщения произошла ошибка, то вызов завершается успешно и возвращается количество отправленных сообщений. Код ошибки теряется. Вызывающий может повторить передачу, начиная с первого ошибочного сообщения, но нет гарантии, что возвращаемый код ошибки будет совпадать с потерянным в предыдущем вызове.

ПРИМЕРЫ

В примере далее sendmmsg() используется для отправки onetwo и three в двух разных дейтаграммах UDP за один системный вызов. Содержимое первой дейтаграммы составляется из пары буферов.
#define _GNU_SOURCE
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
int main(void) { int retval; int sockfd; struct iovec msg1[2], msg2; struct mmsghdr msg[2]; struct sockaddr_in addr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { perror("socket()"); exit(EXIT_FAILURE); }
addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr.sin_port = htons(1234); if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { perror("connect()"); exit(EXIT_FAILURE); }
memset(msg1, 0, sizeof(msg1)); msg1[0].iov_base = "one"; msg1[0].iov_len = 3; msg1[1].iov_base = "two"; msg1[1].iov_len = 3;
memset(&msg2, 0, sizeof(msg2)); msg2.iov_base = "three"; msg2.iov_len = 5;
memset(msg, 0, sizeof(msg)); msg[0].msg_hdr.msg_iov = msg1; msg[0].msg_hdr.msg_iovlen = 2;
msg[1].msg_hdr.msg_iov = &msg2; msg[1].msg_hdr.msg_iovlen = 1;
retval = sendmmsg(sockfd, msg, 2, 0); if (retval == -1) perror("sendmmsg()"); else printf("%d сообщений послано\n", retval);
exit(0); }

СМ. ТАКЖЕ

recvmmsg(2), sendmsg(2), socket(2), socket(7)

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Alexander Golubev <[email protected]>, Azamat Hackimov <[email protected]>, Hotellook, Nikita <[email protected]>, Spiros Georgaras <[email protected]>, Vladislav <[email protected]>, Yuri Kozlov <[email protected]> и Иван Павлов <[email protected]>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на [email protected]

Recommended readings

Pages related to sendmmsg you should read also: