man-pages/man2/recvmmsg.2.html
2021-03-31 01:06:50 +01:00

405 lines
11 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML><HEAD><TITLE>Man page of RECVMMSG</TITLE>
</HEAD><BODY>
<H1>RECVMMSG</H1>
Section: Linux Programmer's Manual (2)<BR>Updated: 2019-03-06<BR><A HREF="#index">Index</A>
<A HREF="/cgi-bin/man/man2html">Return to Main Contents</A><HR>
<A NAME="lbAB">&nbsp;</A>
<H2>NAME</H2>
recvmmsg - receive multiple messages on a socket
<A NAME="lbAC">&nbsp;</A>
<H2>SYNOPSIS</H2>
<PRE>
<B>#define _GNU_SOURCE</B> /* See <A HREF="/cgi-bin/man/man2html?7+feature_test_macros">feature_test_macros</A>(7) */
<B>#include &lt;<A HREF="file:///usr/include/sys/socket.h">sys/socket.h</A>&gt;</B>
<B>int recvmmsg(int </B><I>sockfd</I><B>, struct mmsghdr *</B><I>msgvec</I><B>, unsigned int </B><I>vlen</I><B>,</B>
<B> int </B><I>flags</I><B>, struct timespec *</B><I>timeout</I><B>);</B>
</PRE>
<A NAME="lbAD">&nbsp;</A>
<H2>DESCRIPTION</H2>
The
<B>recvmmsg</B>()
system call is an extension of
<B><A HREF="/cgi-bin/man/man2html?2+recvmsg">recvmsg</A></B>(2)
that allows the caller to receive multiple messages from a socket
using a single system call.
(This has performance benefits for some applications.)
A further extension over
<B><A HREF="/cgi-bin/man/man2html?2+recvmsg">recvmsg</A></B>(2)
is support for a timeout on the receive operation.
<P>
The
<I>sockfd</I>
argument is the file descriptor of the socket to receive data from.
<P>
The
<I>msgvec</I>
argument is a pointer to an array of
<I>mmsghdr</I>
structures.
The size of this array is specified in
<I>vlen</I>.
<P>
The
<I>mmsghdr</I>
structure is defined in
<I>&lt;<A HREF="file:///usr/include/sys/socket.h">sys/socket.h</A>&gt;</I>
as:
<P>
struct mmsghdr {
<BR>&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;msghdr&nbsp;msg_hdr;&nbsp;&nbsp;/*&nbsp;Message&nbsp;header&nbsp;*/
<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;int&nbsp;&nbsp;msg_len;&nbsp;&nbsp;/*&nbsp;Number&nbsp;of&nbsp;received&nbsp;bytes&nbsp;for&nbsp;header&nbsp;*/
};
<P>
The
<I>msg_hdr</I>
field is a
<I>msghdr</I>
structure, as described in
<B><A HREF="/cgi-bin/man/man2html?2+recvmsg">recvmsg</A></B>(2).
The
<I>msg_len</I>
field is the number of bytes returned for the message in the entry.
This field has the same value as the return value of a single
<B><A HREF="/cgi-bin/man/man2html?2+recvmsg">recvmsg</A></B>(2)
on the header.
<P>
The
<I>flags</I>
argument contains flags ORed together.
The flags are the same as documented for
<B><A HREF="/cgi-bin/man/man2html?2+recvmsg">recvmsg</A></B>(2),
with the following addition:
<DL COMPACT>
<DT id="1"><B>MSG_WAITFORONE</B> (since Linux 2.6.34)
<DD>
Turns on
<B>MSG_DONTWAIT</B>
after the first message has been received.
</DL>
<P>
The
<I>timeout</I>
argument points to a
<I>struct timespec</I>
(see
<B><A HREF="/cgi-bin/man/man2html?2+clock_gettime">clock_gettime</A></B>(2))
defining a timeout (seconds plus nanoseconds) for the receive operation
(<I>but see BUGS!</I>).
(This interval will be rounded up to the system clock granularity,
and kernel scheduling delays mean that the blocking interval
may overrun by a small amount.)
If
<I>timeout</I>
is NULL, then the operation blocks indefinitely.
<P>
A blocking
<B>recvmmsg</B>()
call blocks until
<I>vlen</I>
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
<I>vlen</I>)
and returns immediately.
<P>
On return from
<B>recvmmsg</B>(),
successive elements of
<I>msgvec</I>
are updated to contain information about each received message:
<I>msg_len</I>
contains the size of the received message;
the subfields of
<I>msg_hdr</I>
are updated as described in
<B><A HREF="/cgi-bin/man/man2html?2+recvmsg">recvmsg</A></B>(2).
The return value of the call indicates the number of elements of
<I>msgvec</I>
that have been updated.
<A NAME="lbAE">&nbsp;</A>
<H2>RETURN VALUE</H2>
On success,
<B>recvmmsg</B>()
returns the number of messages received in
<I>msgvec</I>;
on error, -1 is returned, and
<I>errno</I>
is set to indicate the error.
<A NAME="lbAF">&nbsp;</A>
<H2>ERRORS</H2>
Errors are as for
<B><A HREF="/cgi-bin/man/man2html?2+recvmsg">recvmsg</A></B>(2).
In addition, the following error can occur:
<DL COMPACT>
<DT id="2"><B>EINVAL</B>
<DD>
<I>timeout</I>
is invalid.
</DL>
<P>
See also BUGS.
<A NAME="lbAG">&nbsp;</A>
<H2>VERSIONS</H2>
The
<B>recvmmsg</B>()
system call was added in Linux 2.6.33.
Support in glibc was added in version 2.12.
<A NAME="lbAH">&nbsp;</A>
<H2>CONFORMING TO</H2>
<B>recvmmsg</B>()
is Linux-specific.
<A NAME="lbAI">&nbsp;</A>
<H2>BUGS</H2>
The
<I>timeout</I>
argument does not work as intended.
The timeout is checked only after the receipt of each datagram,
so that if up to
<I>vlen-1</I>
datagrams are received before the timeout expires,
but then no further datagrams are received, the call will block forever.
<P>
If an error occurs after at least one message has been received,
the call succeeds, and returns the number of messages received.
The error code is expected to be returned on a subsequent call to
<B>recvmmsg</B>().
In the current implementation, however, the error code can be overwritten
in the meantime by an unrelated network event on a socket,
for example an incoming ICMP packet.
<A NAME="lbAJ">&nbsp;</A>
<H2>EXAMPLE</H2>
<P>
The following program uses
<B>recvmmsg</B>()
to receive multiple messages on a socket and stores
them in multiple buffers.
The call returns if all buffers are filled or if the
timeout specified has expired.
<P>
The following snippet periodically generates UDP datagrams
containing a random number:
<P>
$<B> while true; do echo $RANDOM &gt; /dev/udp/127.0.0.1/1234; </B>
<B> sleep 0.25; done</B>
<P>
These datagrams are read by the example application, which
can give the following output:
<P>
$<B> ./a.out</B>
5 messages received
1 11782
2 11345
3 304
4 13514
5 28421
<A NAME="lbAK">&nbsp;</A>
<H3>Program source</H3>
#define _GNU_SOURCE
#include &lt;<A HREF="file:///usr/include/netinet/ip.h">netinet/ip.h</A>&gt;
#include &lt;<A HREF="file:///usr/include/stdio.h">stdio.h</A>&gt;
#include &lt;<A HREF="file:///usr/include/stdlib.h">stdlib.h</A>&gt;
#include &lt;<A HREF="file:///usr/include/string.h">string.h</A>&gt;
#include &lt;<A HREF="file:///usr/include/sys/socket.h">sys/socket.h</A>&gt;
<P>
int
main(void)
{
#define VLEN 10
#define BUFSIZE 200
#define TIMEOUT 1
<BR>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;sockfd,&nbsp;retval,&nbsp;i;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;sockaddr_in&nbsp;addr;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;mmsghdr&nbsp;msgs[VLEN];
<BR>&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;iovec&nbsp;iovecs[VLEN];
<BR>&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;bufs[VLEN][BUFSIZE+1];
<BR>&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;timespec&nbsp;timeout;
<P>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;sockfd&nbsp;=&nbsp;socket(AF_INET,&nbsp;SOCK_DGRAM,&nbsp;0);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(sockfd&nbsp;==&nbsp;-1)&nbsp;{
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;socket()&quot;);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;}
<P>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;addr.sin_family&nbsp;=&nbsp;AF_INET;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;addr.sin_addr.s_addr&nbsp;=&nbsp;htonl(INADDR_LOOPBACK);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;addr.sin_port&nbsp;=&nbsp;htons(1234);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(bind(sockfd,&nbsp;(struct&nbsp;sockaddr&nbsp;*)&nbsp;&amp;addr,&nbsp;sizeof(addr))&nbsp;==&nbsp;-1)&nbsp;{
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;bind()&quot;);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;}
<P>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;memset(msgs,&nbsp;0,&nbsp;sizeof(msgs));
<BR>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;VLEN;&nbsp;i++)&nbsp;{
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iovecs[i].iov_base&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;bufs[i];
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iovecs[i].iov_len&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;BUFSIZE;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msgs[i].msg_hdr.msg_iov&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&amp;iovecs[i];
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msgs[i].msg_hdr.msg_iovlen&nbsp;=&nbsp;1;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;}
<P>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;timeout.tv_sec&nbsp;=&nbsp;TIMEOUT;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;timeout.tv_nsec&nbsp;=&nbsp;0;
<P>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;retval&nbsp;=&nbsp;recvmmsg(sockfd,&nbsp;msgs,&nbsp;VLEN,&nbsp;0,&nbsp;&amp;timeout);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(retval&nbsp;==&nbsp;-1)&nbsp;{
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;recvmmsg()&quot;);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;}
<P>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;%d&nbsp;messages&nbsp;received\n&quot;,&nbsp;retval);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;retval;&nbsp;i++)&nbsp;{
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bufs[i][msgs[i].msg_len]&nbsp;=&nbsp;0;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;%d&nbsp;%s&quot;,&nbsp;i+1,&nbsp;bufs[i]);
<BR>&nbsp;&nbsp;&nbsp;&nbsp;}
<BR>&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_SUCCESS);
}
<A NAME="lbAL">&nbsp;</A>
<H2>SEE ALSO</H2>
<B><A HREF="/cgi-bin/man/man2html?2+clock_gettime">clock_gettime</A></B>(2),
<B><A HREF="/cgi-bin/man/man2html?2+recvmsg">recvmsg</A></B>(2),
<B><A HREF="/cgi-bin/man/man2html?2+sendmmsg">sendmmsg</A></B>(2),
<B><A HREF="/cgi-bin/man/man2html?2+sendmsg">sendmsg</A></B>(2),
<B><A HREF="/cgi-bin/man/man2html?2+socket">socket</A></B>(2),
<B><A HREF="/cgi-bin/man/man2html?7+socket">socket</A></B>(7)
<A NAME="lbAM">&nbsp;</A>
<H2>COLOPHON</H2>
This page is part of release 5.05 of the Linux
<I>man-pages</I>
project.
A description of the project,
information about reporting bugs,
and the latest version of this page,
can be found at
<A HREF="https://www.kernel.org/doc/man-pages/.">https://www.kernel.org/doc/man-pages/.</A>
<P>
<HR>
<A NAME="index">&nbsp;</A><H2>Index</H2>
<DL>
<DT id="3"><A HREF="#lbAB">NAME</A><DD>
<DT id="4"><A HREF="#lbAC">SYNOPSIS</A><DD>
<DT id="5"><A HREF="#lbAD">DESCRIPTION</A><DD>
<DT id="6"><A HREF="#lbAE">RETURN VALUE</A><DD>
<DT id="7"><A HREF="#lbAF">ERRORS</A><DD>
<DT id="8"><A HREF="#lbAG">VERSIONS</A><DD>
<DT id="9"><A HREF="#lbAH">CONFORMING TO</A><DD>
<DT id="10"><A HREF="#lbAI">BUGS</A><DD>
<DT id="11"><A HREF="#lbAJ">EXAMPLE</A><DD>
<DL>
<DT id="12"><A HREF="#lbAK">Program source</A><DD>
</DL>
<DT id="13"><A HREF="#lbAL">SEE ALSO</A><DD>
<DT id="14"><A HREF="#lbAM">COLOPHON</A><DD>
</DL>
<HR>
This document was created by
<A HREF="/cgi-bin/man/man2html">man2html</A>,
using the manual pages.<BR>
Time: 00:05:34 GMT, March 31, 2021
</BODY>
</HTML>