Provided by: manpages-ru-dev_4.27.0-1_all bug

НАИМЕНОВАНИЕ

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

БИБЛИОТЕКА

       Стандартная библиотека языка C (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). Ошибка возвращается только, если  ни  одной  дейтаграммы  не
       послано. Смотрите также ДЕФЕКТЫ.

СТАНДАРТЫ

       Linux.

ИСТОРИЯ

       Linux 3.0, glibc 2.14.

ПРИМЕЧАНИЯ

       Значение, указанное в 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 messages sent\n", retval);

           exit(0);
       }

СМОТРИТЕ ТАКЖЕ

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

ПЕРЕВОД

       Русский перевод этой страницы руководства разработал(и)  Alexander  Golubev  <fatzer2@gmail.com>,  Azamat
       Hackimov   <azamat.hackimov@gmail.com>,   Hotellook,   Nikita   <zxcvbnm3230@mail.ru>,  Spiros  Georgaras
       <sng@hellug.gr>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov  <yuray@komyakino.ru>,  Иван  Павлов
       <pavia00@gmail.com> и Kirill Rekhov <krekhov.dev@gmail.com>

       Этот  перевод является свободной программной документацией; он распространяется на условиях общедоступной
       лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html  версии  3  или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если  вы  обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом
       разработчику(ам)  по  его(их)  адресу(ам)  электронной  почты  или  по   адресу   списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                  15 июня 2024 г.                                     sendmmsg(2)