sendmmsg — send multiple messages on a socket
#define _GNU_SOURCE /* See feature_test_macros(7) */ #include <sys/socket.h>
int
sendmmsg( |
int sockfd, |
struct mmsghdr *msgvec, | |
unsigned int vlen, | |
unsigned int flags) ; |
The sendmmsg
() system call
is an extension of sendmsg(2) that allows the
caller to transmit multiple messages on a socket using a
single system call. (This has performance benefits for some
applications.)
The sockfd
argument is the file descriptor of the socket on which data
is to be transmitted.
The msgvec
argument is a pointer to an array of mmsghdr structures. The size of this
array is specified in vlen
.
The mmsghdr structure is
defined in <
sys/socket.h
>
as:
struct mmsghdr { struct msghdr msg_hdr
; /* Message header */unsigned int msg_len
; /* Number of bytes transmitted */};
The msg_hdr
field
is a msghdr
structure, as described in sendmsg(2). The msg_len
field is used to return
the number of bytes sent from the message in msg_hdr
(i.e., the same as the
return value from a single sendmsg(2) call).
The flags
argument
contains flags ORed together. The flags are the same as for
sendmsg(2).
A blocking sendmmsg
() call
blocks until vlen
messages have been sent. A nonblocking call sends as many
messages as possible (up to the limit specified by vlen
) and returns
immediately.
On return from sendmmsg
(),
the msg_len
fields of
successive elements of msgvec
are updated to contain
the number of bytes transmitted from the corresponding
msg_hdr
. The return
value of the call indicates the number of elements of
msgvec
that have been
updated.
On success, sendmmsg
()
returns the number of messages sent from msgvec
; if this is less than
vlen
, the caller can
retry with a further sendmmsg
()
call to send the remaining messages.
On error, −1 is returned, and errno
is set to indicate the error.
The sendmmsg
() system call
was added in Linux 3.0. Support in glibc was added in version
2.14.
The example below uses sendmmsg
() to send onetwo
and three
in two distinct UDP
datagrams using one system call. The contents of the first
datagram originates from a pair of buffers.
#define _GNU_SOURCE #include <netinet/ip.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> int main(void) { int sockfd; struct sockaddr_in addr; struct mmsghdr msg[2]; struct iovec msg1[2], msg2; int retval; 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); }
This page is part of release 4.07 of the Linux man-pages
project. A
description of the project, information about reporting bugs,
and the latest version of this page, can be found at
https://www.kernel.org/doc/man−pages/.
Copyright (c) 2012 by Michael Kerrisk <mtk.manpagesgmail.com> with some material from a draft by Stephan Mueller <stephan.muelleratsec.com> in turn based on Andi Kleen's recvmmsg.2 page. %%%LICENSE_START(VERBATIM) Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Since the Linux kernel and libraries are constantly changing, this manual page may be incorrect or out-of-date. The author(s) assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein. The author(s) may not have taken the same level of care in the production of this manual, which is licensed free of charge, as they might when working professionally. Formatted or processed versions of this manual, if unaccompanied by the source, must acknowledge the copyright and authors of this work. %%%LICENSE_END |