mirror of https://github.com/mkerrisk/man-pages
recvmmsg.2: Add an example program
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
parent
e3b419fae8
commit
f2246260a9
|
@ -21,8 +21,6 @@
|
|||
.\" Formatted or processed versions of this manual, if unaccompanied by
|
||||
.\" the source, must acknowledge the copyright and authors of this work.
|
||||
.\"
|
||||
.\" FIXME: This page could be improved with an example program.
|
||||
.\"
|
||||
.TH RECVMMSG 2 2012-05-02 "Linux" "Linux Programmer's Manual"
|
||||
.SH NAME
|
||||
recvmmsg \- receive multiple messages on a socket
|
||||
|
@ -165,6 +163,98 @@ Support in glibc was added in version 2.12.
|
|||
.SH CONFORMING TO
|
||||
.BR recvmmsg ()
|
||||
is Linux-specific.
|
||||
.SH EXAMPLE
|
||||
.PP
|
||||
The following program uses
|
||||
.BR recvmmsg ()
|
||||
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 is expired.
|
||||
|
||||
The following snippet periodically generates UDP datagrams
|
||||
containing a random number:
|
||||
.in +4n
|
||||
.nf
|
||||
.RB "$" " while true; do echo $RANDOM > /dev/udp/127.0.0.1/1234; sleep 0.25; done"
|
||||
.fi
|
||||
.in
|
||||
|
||||
These datagrams are read by the example application which
|
||||
can give the following output:
|
||||
.in +4n
|
||||
.nf
|
||||
.RB "$" " ./a.out"
|
||||
5 messages received
|
||||
1 11782
|
||||
2 11345
|
||||
3 304
|
||||
4 13514
|
||||
5 28421
|
||||
.fi
|
||||
.in
|
||||
.SS Program source
|
||||
\&
|
||||
.nf
|
||||
#define _GNU_SOURCE
|
||||
#include <netinet/ip.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
#define VLEN 10
|
||||
#define BUFSIZE 200
|
||||
#define TIMEOUT 1
|
||||
int sockfd, retval, i;
|
||||
struct sockaddr_in sa;
|
||||
struct mmsghdr msgs[VLEN];
|
||||
struct iovec iovecs[VLEN];
|
||||
char bufs[VLEN][BUFSIZE+1];
|
||||
struct timespec timeout;
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd == \-1) {
|
||||
perror("socket()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
sa.sin_port = htons(1234);
|
||||
if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == \-1) {
|
||||
perror("bind()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset(msgs, 0, sizeof(msgs));
|
||||
for (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 (i = 0; i < retval; i++) {
|
||||
bufs[i][msgs[i].msg_len] = 0;
|
||||
printf("%d %s", i+1, bufs[i]);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
.fi
|
||||
.SH SEE ALSO
|
||||
.BR clock_gettime (2),
|
||||
.BR recvmsg (2),
|
||||
|
|
Loading…
Reference in New Issue