recvmmsg(2) System Calls Manual recvmmsg(2) recvmmsg - Standard C library (libc, -lc) #define _GNU_SOURCE /* feature_test_macros(7) */ #include int recvmmsg(int sockfd, struct mmsghdr msgvec[.n], unsigned int n, int flags, struct timespec *timeout); recvmmsg() recvmsg(2), , ( ). recvmsg(2) -- . sockfd . The msgvec argument is a pointer to an array of mmsghdr structures. The size of this array is specified in n. mmsghdr : struct mmsghdr { struct msghdr msg_hdr; /* */ unsigned int msg_len; /* */ }; msg_hdr msghdr, recvmsg(2). msg_len . , recvmsg(2) . flags OR . , recvmsg(2), : MSG_WAITFORONE ( Linux 2.6.34) MSG_DONTWAIT . timeout struct timespec ( clock_gettime(2)), ( ) ( !; ( , - ). timeout NULL, . A blocking recvmmsg() call blocks until n 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 n) and returns immediately. recvmmsg() msgvec : msg_len ; msg_hdr recvmsg(2). msgvec. recvmmsg() msgvec ; -1 errno . recvmsg(2). , : EINVAL timeout . . Linux. Linux 2.6.33, glibc 2.12. The timeout argument does not work as intended. The timeout is checked only after the receipt of each datagram, so that if up to n-1 datagrams are received before the timeout expires, but then no further datagrams are received, the call will block forever. , . recvmmsg(). , , , - ICMP. recvmmsg() . , . UDP : $ while true; do echo $RANDOM > /dev/udp/127.0.0.1/1234; sleep 0.25; done , : $ ./a.out 5 1 11782 2 11345 3 304 4 13514 5 28421 #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\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); } clock_gettime(2), recvmsg(2), sendmmsg(2), sendmsg(2), socket(2), socket(7) () aereiae , Azamat Hackimov , Dmitriy S. Seregin , Katrin Kutepova , Lockal , Yuri Kozlov , , Kirill Rekhov ; GNU (GNU General Public License - GPL, 3 ) , - . - , , () () () <>. Linux man-pages 6.12 17 2024 . recvmmsg(2)