.\" -*- coding: UTF-8 -*- .\" Copyright (C) 2011 by Andi Kleen .\" and Copyright (c) 2011 by Michael Kerrisk .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\" Syscall added in following commit .\" commit a2e2725541fad72416326798c2d7fa4dafb7d337 .\" Author: Arnaldo Carvalho de Melo .\" Date: Mon Oct 12 23:40:10 2009 -0700 .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH recvmmsg 2 "17 ноября 2024 г." "Linux man\-pages 6.12" .SH НАИМЕНОВАНИЕ recvmmsg \- получает несколько сообщений из сокета .SH БИБЛИОТЕКА Standard C library (\fIlibc\fP,\ \fI\-lc\fP) .SH ОБЗОР .nf \fB#define _GNU_SOURCE\fP /* Смотрите feature_test_macros(7) */ \fB#include \fP .P \fBint recvmmsg(int \fP\fIsockfd\fP\fB, struct mmsghdr \fP\fImsgvec\fP\fB[.\fP\fIn\fP\fB], unsigned int \fP\fIn\fP\fB,\fP \fB int \fP\fIflags\fP\fB, struct timespec *\fP\fItimeout\fP\fB);\fP .fi .SH ОПИСАНИЕ Системный вызов \fBrecvmmsg\fP() является расширенной версией \fBrecvmsg\fP(2), позволяя вызывающему получать несколько сообщений из сокета, используя только один системный вызов (в некоторых приложениях это позволяет получить выигрыш в производительности). Ещё одно улучшение \fBrecvmsg\fP(2) — настройка времени ожидания для операции получения. .P Аргумент \fIsockfd\fP представляет собой файловый дескриптор сокета приёма данных. .P The \fImsgvec\fP argument is a pointer to an array of \fImmsghdr\fP structures. The size of this array is specified in \fIn\fP. .P Структура \fImmsghdr\fP определена в \fI\fP следующим образом: .P .in +4n .EX struct mmsghdr { struct msghdr msg_hdr; /* Заголовок сообщения */ unsigned int msg_len; /* Количество полученных байт для заголовка */ }; .EE .in .P Поле \fImsg_hdr\fP представляет собой структуру \fImsghdr\fP, которая описана в \fBrecvmsg\fP(2). В поле \fImsg_len\fP содержится количество байт возвращаемого сообщения в записи. Это поле имеет такое же значение, что и возвращаемое значение одиночного вызова \fBrecvmsg\fP(2) в заголовке. .P Аргумент \fIflags\fP содержит объединённые с помощью OR флаги. Флаги те же, что и у \fBrecvmsg\fP(2), но со следующим дополнением: .TP \fBMSG_WAITFORONE\fP (начиная с Linux 2.6.34) Включить \fBMSG_DONTWAIT\fP после получения первого сообщения. .P Аргумент \fItimeout\fP указывает на \fIstruct timespec\fP (смотрите \fBclock_gettime\fP(2)), задающую время ожидания (в секундах и наносекундах) операции приёма (\fIно смотрите ДЕФЕКТЫ!\fP; (этот интервал будет округлён до точности системных часов, и из\-за задержек планировщика ядра интервал блокировки может быть немного больше). Если \fItimeout\fP равно NULL, то операция блокируется на неопределённое время. .P A blocking \fBrecvmmsg\fP() call blocks until \fIn\fP messages have been received or until the timeout expires. A nonblocking call reads as many messages as are available (up to the limit specified by \fIn\fP) and returns immediately. .P При выходе из \fBrecvmmsg\fP() последующие элементы \fImsgvec\fP обновляются информацией о каждом полученном сообщении: в \fImsg_len\fP содержится размер принятого сообщения; подполя \fImsg_hdr\fP обновляются согласно описанию в \fBrecvmsg\fP(2). Возвращаемое значение вызова означает количество обновлённых элементов \fImsgvec\fP. .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" При успешном выполнении \fBrecvmmsg\fP() возвращает количество принятых в \fImsgvec\fP сообщений; при ошибке возвращается \-1 и в \fIerrno\fP устанавливается код ошибки. .SH ОШИБКИ Возникают те же ошибки что и для \fBrecvmsg\fP(2). Кроме этого, случается следующая ошибка: .TP \fBEINVAL\fP Значение \fItimeout\fP неверно. .P Также смотрите ДЕФЕКТЫ. .SH СТАНДАРТЫ Linux. .SH ИСТОРИЯ Linux 2.6.33, glibc 2.12. .SH ОШИБКИ .\" FIXME . https://bugzilla.kernel.org/show_bug.cgi?id=75371 .\" http://thread.gmane.org/gmane.linux.man/5677 The \fItimeout\fP argument does not work as intended. The timeout is checked only after the receipt of each datagram, so that if up to \fIn\-1\fP datagrams are received before the timeout expires, but then no further datagrams are received, the call will block forever. .P Если ошибка возникает после получения хотя бы одного сообщения, то вызов выполняется успешно и возвращается количество полученных сообщений. Код ошибки будет возвращён следующим вызовом \fBrecvmmsg\fP(). Однако в текущей реализации код ошибки может перезаписаться при возникновении в тоже время события, не связанного с сетью, например, из\-за поступившего пакета ICMP. .SH ПРИМЕРЫ Следующая программа использует \fBrecvmmsg\fP() для получения нескольких сообщений через сокет и сохранения их в несколько буферов. Вызов завершается при заполнении всех буферов, либо по окончании заданного временного интервала. .P Следующий отрывок периодически генерирует датаграммы UDP с произвольным номером внутри: .P .in +4n .EX $\fB while true; do echo $RANDOM > /dev/udp/127.0.0.1/1234;\fP \fBsleep 0.25; done\fP .EE .in .P Эти датаграммы читаются примером приложения, который выдаёт: .P .in +4n .EX $\fB ./a.out\fP 5 сообщений получено 1 11782 2 11345 3 304 4 13514 5 28421 .EE .in .SS "Исходный код программы" .\" SRC BEGIN (recvmmsg.c) \& .EX #define _GNU_SOURCE #include #include #include #include #include #include #include \& int main(void) { #define VLEN 10 #define BUFSIZE 200 #define TIMEOUT 1 int sockfd, retval; char bufs[VLEN][BUFSIZE+1]; struct iovec iovecs[VLEN]; struct mmsghdr msgs[VLEN]; struct timespec timeout; 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 (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == \-1) { perror("bind()"); exit(EXIT_FAILURE); } \& memset(msgs, 0, sizeof(msgs)); for (size_t i = 0; i < VLEN; i++) { iovecs[i].iov_base = bufs[i]; iovecs[i].iov_len = BUFSIZE; msgs[i].msg_hdr.msg_iov = &iovecs[i]; msgs[i].msg_hdr.msg_iovlen = 1; } \& timeout.tv_sec = TIMEOUT; timeout.tv_nsec = 0; \& retval = recvmmsg(sockfd, msgs, VLEN, 0, &timeout); if (retval == \-1) { perror("recvmmsg()"); exit(EXIT_FAILURE); } \& printf("%d messages received\[rs]n", retval); for (size_t i = 0; i < retval; i++) { bufs[i][msgs[i].msg_len] = 0; printf("%zu %s", i+1, bufs[i]); } exit(EXIT_SUCCESS); } .EE .\" SRC END .SH "СМОТРИТЕ ТАКЖЕ" \fBclock_gettime\fP(2), \fBrecvmsg\fP(2), \fBsendmmsg\fP(2), \fBsendmsg\fP(2), \fBsocket\fP(2), \fBsocket\fP(7) .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства разработал(и) aereiae , Azamat Hackimov , Dmitriy S. Seregin , Katrin Kutepova , Lockal , Yuri Kozlov , Баринов Владимир, Иван Павлов и Kirill Rekhov . .PP Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, .UR https://www.gnu.org/licenses/gpl-3.0.html .UE версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ. .PP Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу .MT списка рассылки русских переводчиков .ME .