|
Packit |
7cfc04 |
.\" Copyright (c) 2012 by Michael Kerrisk <mtk.manpages@gmail.com>
|
|
Packit |
7cfc04 |
.\" with some material from a draft by
|
|
Packit |
7cfc04 |
.\" Stephan Mueller <stephan.mueller@atsec.com>
|
|
Packit |
7cfc04 |
.\" in turn based on Andi Kleen's recvmmsg.2 page.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" %%%LICENSE_START(VERBATIM)
|
|
Packit |
7cfc04 |
.\" Permission is granted to make and distribute verbatim copies of this
|
|
Packit |
7cfc04 |
.\" manual provided the copyright notice and this permission notice are
|
|
Packit |
7cfc04 |
.\" preserved on all copies.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" Permission is granted to copy and distribute modified versions of this
|
|
Packit |
7cfc04 |
.\" manual under the conditions for verbatim copying, provided that the
|
|
Packit |
7cfc04 |
.\" entire resulting derived work is distributed under the terms of a
|
|
Packit |
7cfc04 |
.\" permission notice identical to this one.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" Since the Linux kernel and libraries are constantly changing, this
|
|
Packit |
7cfc04 |
.\" manual page may be incorrect or out-of-date. The author(s) assume no
|
|
Packit |
7cfc04 |
.\" responsibility for errors or omissions, or for damages resulting from
|
|
Packit |
7cfc04 |
.\" the use of the information contained herein. The author(s) may not
|
|
Packit |
7cfc04 |
.\" have taken the same level of care in the production of this manual,
|
|
Packit |
7cfc04 |
.\" which is licensed free of charge, as they might when working
|
|
Packit |
7cfc04 |
.\" professionally.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" Formatted or processed versions of this manual, if unaccompanied by
|
|
Packit |
7cfc04 |
.\" the source, must acknowledge the copyright and authors of this work.
|
|
Packit |
7cfc04 |
.\" %%%LICENSE_END
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.TH SENDMMSG 2 2018-02-02 "Linux" "Linux Programmer's Manual"
|
|
Packit |
7cfc04 |
.SH NAME
|
|
Packit |
7cfc04 |
sendmmsg \- send multiple messages on a socket
|
|
Packit |
7cfc04 |
.SH SYNOPSIS
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
|
|
Packit |
7cfc04 |
.BI "#include <sys/socket.h>"
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BI "int sendmmsg(int " sockfd ", struct mmsghdr *" msgvec \
|
|
Packit |
7cfc04 |
", unsigned int " vlen ","
|
|
Packit |
7cfc04 |
.BI " int " flags ");"
|
|
Packit |
7cfc04 |
.fi
|
|
Packit |
7cfc04 |
.SH DESCRIPTION
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.BR sendmmsg ()
|
|
Packit |
7cfc04 |
system call is an extension of
|
|
Packit |
7cfc04 |
.BR sendmsg (2)
|
|
Packit |
7cfc04 |
that allows the caller to transmit multiple messages on a socket
|
|
Packit |
7cfc04 |
using a single system call.
|
|
Packit |
7cfc04 |
(This has performance benefits for some applications.)
|
|
Packit |
7cfc04 |
.\" See commit 228e548e602061b08ee8e8966f567c12aa079682
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.I sockfd
|
|
Packit |
7cfc04 |
argument is the file descriptor of the socket
|
|
Packit |
7cfc04 |
on which data is to be transmitted.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.I msgvec
|
|
Packit |
7cfc04 |
argument is a pointer to an array of
|
|
Packit |
7cfc04 |
.I mmsghdr
|
|
Packit |
7cfc04 |
structures.
|
|
Packit |
7cfc04 |
The size of this array is specified in
|
|
Packit |
7cfc04 |
.IR vlen .
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.I mmsghdr
|
|
Packit |
7cfc04 |
structure is defined in
|
|
Packit |
7cfc04 |
.I <sys/socket.h>
|
|
Packit |
7cfc04 |
as:
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in +4n
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
struct mmsghdr {
|
|
Packit |
7cfc04 |
struct msghdr msg_hdr; /* Message header */
|
|
Packit |
7cfc04 |
unsigned int msg_len; /* Number of bytes transmitted */
|
|
Packit |
7cfc04 |
};
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.I msg_hdr
|
|
Packit |
7cfc04 |
field is a
|
|
Packit |
7cfc04 |
.I msghdr
|
|
Packit |
7cfc04 |
structure, as described in
|
|
Packit |
7cfc04 |
.BR sendmsg (2).
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.I msg_len
|
|
Packit |
7cfc04 |
field is used to return the number of bytes sent from the message in
|
|
Packit |
7cfc04 |
.IR msg_hdr
|
|
Packit |
7cfc04 |
(i.e., the same as the return value from a single
|
|
Packit |
7cfc04 |
.BR sendmsg (2)
|
|
Packit |
7cfc04 |
call).
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.I flags
|
|
Packit |
7cfc04 |
argument contains flags ORed together.
|
|
Packit |
7cfc04 |
The flags are the same as for
|
|
Packit |
7cfc04 |
.BR sendmsg (2).
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
A blocking
|
|
Packit |
7cfc04 |
.BR sendmmsg ()
|
|
Packit |
7cfc04 |
call blocks until
|
|
Packit |
7cfc04 |
.I vlen
|
|
Packit |
7cfc04 |
messages have been sent.
|
|
Packit |
7cfc04 |
A nonblocking call sends as many messages as possible
|
|
Packit |
7cfc04 |
(up to the limit specified by
|
|
Packit |
7cfc04 |
.IR vlen )
|
|
Packit |
7cfc04 |
and returns immediately.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
On return from
|
|
Packit |
7cfc04 |
.BR sendmmsg (),
|
|
Packit |
7cfc04 |
the
|
|
Packit |
7cfc04 |
.I msg_len
|
|
Packit |
7cfc04 |
fields of successive elements of
|
|
Packit |
7cfc04 |
.IR msgvec
|
|
Packit |
7cfc04 |
are updated to contain the number of bytes transmitted from the corresponding
|
|
Packit |
7cfc04 |
.IR msg_hdr .
|
|
Packit |
7cfc04 |
The return value of the call indicates the number of elements of
|
|
Packit |
7cfc04 |
.I msgvec
|
|
Packit |
7cfc04 |
that have been updated.
|
|
Packit |
7cfc04 |
.SH RETURN VALUE
|
|
Packit |
7cfc04 |
On success,
|
|
Packit |
7cfc04 |
.BR sendmmsg ()
|
|
Packit |
7cfc04 |
returns the number of messages sent from
|
|
Packit |
7cfc04 |
.IR msgvec ;
|
|
Packit |
7cfc04 |
if this is less than
|
|
Packit |
7cfc04 |
.IR vlen ,
|
|
Packit |
7cfc04 |
the caller can retry with a further
|
|
Packit |
7cfc04 |
.BR sendmmsg ()
|
|
Packit |
7cfc04 |
call to send the remaining messages.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
On error, \-1 is returned, and
|
|
Packit |
7cfc04 |
.I errno
|
|
Packit |
7cfc04 |
is set to indicate the error.
|
|
Packit |
7cfc04 |
.SH ERRORS
|
|
Packit |
7cfc04 |
Errors are as for
|
|
Packit |
7cfc04 |
.BR sendmsg (2).
|
|
Packit |
7cfc04 |
An error is returned only if no datagrams could be sent.
|
|
Packit |
7cfc04 |
See also BUGS.
|
|
Packit |
7cfc04 |
.\" commit 728ffb86f10873aaf4abd26dde691ee40ae731fe
|
|
Packit |
7cfc04 |
.\" ... only return an error if no datagrams could be sent.
|
|
Packit |
7cfc04 |
.\" If less than the requested number of messages were sent, the application
|
|
Packit |
7cfc04 |
.\" must retry starting at the first failed one and if the problem is
|
|
Packit |
7cfc04 |
.\" persistent the error will be returned.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" This matches the behavior of other syscalls like read/write - it
|
|
Packit |
7cfc04 |
.\" is not an error if less than the requested number of elements are sent.
|
|
Packit |
7cfc04 |
.SH VERSIONS
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.BR sendmmsg ()
|
|
Packit |
7cfc04 |
system call was added in Linux 3.0.
|
|
Packit |
7cfc04 |
Support in glibc was added in version 2.14.
|
|
Packit |
7cfc04 |
.SH CONFORMING TO
|
|
Packit |
7cfc04 |
.BR sendmmsg ()
|
|
Packit |
7cfc04 |
is Linux-specific.
|
|
Packit |
7cfc04 |
.SH NOTES
|
|
Packit |
7cfc04 |
The value specified in
|
|
Packit |
7cfc04 |
.I vlen
|
|
Packit |
7cfc04 |
is capped to
|
|
Packit |
7cfc04 |
.B UIO_MAXIOV
|
|
Packit |
7cfc04 |
(1024).
|
|
Packit |
7cfc04 |
.\" commit 98382f419f32d2c12d021943b87dea555677144b
|
|
Packit |
7cfc04 |
.\" net: Cap number of elements for sendmmsg
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" To limit the amount of time we can spend in sendmmsg, cap the
|
|
Packit |
7cfc04 |
.\" number of elements to UIO_MAXIOV (currently 1024).
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" For error handling an application using sendmmsg needs to retry at
|
|
Packit |
7cfc04 |
.\" the first unsent message, so capping is simpler and requires less
|
|
Packit |
7cfc04 |
.\" application logic than returning EINVAL.
|
|
Packit |
7cfc04 |
.SH BUGS
|
|
Packit |
7cfc04 |
If an error occurs after at least one message has been sent,
|
|
Packit |
7cfc04 |
the call succeeds, and returns the number of messages sent.
|
|
Packit |
7cfc04 |
The error code is lost.
|
|
Packit |
7cfc04 |
The caller can retry the transmission,
|
|
Packit |
7cfc04 |
starting at the first failed message, but there is no guarantee that,
|
|
Packit |
7cfc04 |
if an error is returned, it will be the same as the one that was lost
|
|
Packit |
7cfc04 |
on the previous call.
|
|
Packit |
7cfc04 |
.SH EXAMPLE
|
|
Packit |
7cfc04 |
The example below uses
|
|
Packit |
7cfc04 |
.BR sendmmsg ()
|
|
Packit |
7cfc04 |
to send
|
|
Packit |
7cfc04 |
.I onetwo
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.I three
|
|
Packit |
7cfc04 |
in two distinct UDP datagrams using one system call.
|
|
Packit |
7cfc04 |
The contents of the first datagram originates from a pair of buffers.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.EX
|
|
Packit |
7cfc04 |
#define _GNU_SOURCE
|
|
Packit |
7cfc04 |
#include <netinet/ip.h>
|
|
Packit |
7cfc04 |
#include <stdio.h>
|
|
Packit |
7cfc04 |
#include <stdlib.h>
|
|
Packit |
7cfc04 |
#include <string.h>
|
|
Packit |
7cfc04 |
#include <sys/types.h>
|
|
Packit |
7cfc04 |
#include <sys/socket.h>
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
int
|
|
Packit |
7cfc04 |
main(void)
|
|
Packit |
7cfc04 |
{
|
|
Packit |
7cfc04 |
int sockfd;
|
|
Packit |
7cfc04 |
struct sockaddr_in addr;
|
|
Packit |
7cfc04 |
struct mmsghdr msg[2];
|
|
Packit |
7cfc04 |
struct iovec msg1[2], msg2;
|
|
Packit |
7cfc04 |
int retval;
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
Packit |
7cfc04 |
if (sockfd == \-1) {
|
|
Packit |
7cfc04 |
perror("socket()");
|
|
Packit |
7cfc04 |
exit(EXIT_FAILURE);
|
|
Packit |
7cfc04 |
}
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
addr.sin_family = AF_INET;
|
|
Packit |
7cfc04 |
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
Packit |
7cfc04 |
addr.sin_port = htons(1234);
|
|
Packit |
7cfc04 |
if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == \-1) {
|
|
Packit |
7cfc04 |
perror("connect()");
|
|
Packit |
7cfc04 |
exit(EXIT_FAILURE);
|
|
Packit |
7cfc04 |
}
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
memset(msg1, 0, sizeof(msg1));
|
|
Packit |
7cfc04 |
msg1[0].iov_base = "one";
|
|
Packit |
7cfc04 |
msg1[0].iov_len = 3;
|
|
Packit |
7cfc04 |
msg1[1].iov_base = "two";
|
|
Packit |
7cfc04 |
msg1[1].iov_len = 3;
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
memset(&msg2, 0, sizeof(msg2));
|
|
Packit |
7cfc04 |
msg2.iov_base = "three";
|
|
Packit |
7cfc04 |
msg2.iov_len = 5;
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
memset(msg, 0, sizeof(msg));
|
|
Packit |
7cfc04 |
msg[0].msg_hdr.msg_iov = msg1;
|
|
Packit |
7cfc04 |
msg[0].msg_hdr.msg_iovlen = 2;
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
msg[1].msg_hdr.msg_iov = &msg;;
|
|
Packit |
7cfc04 |
msg[1].msg_hdr.msg_iovlen = 1;
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
retval = sendmmsg(sockfd, msg, 2, 0);
|
|
Packit |
7cfc04 |
if (retval == \-1)
|
|
Packit |
7cfc04 |
perror("sendmmsg()");
|
|
Packit |
7cfc04 |
else
|
|
Packit |
7cfc04 |
printf("%d messages sent\\n", retval);
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
exit(0);
|
|
Packit |
7cfc04 |
}
|
|
Packit |
7cfc04 |
.EE
|
|
Packit |
7cfc04 |
.SH SEE ALSO
|
|
Packit |
7cfc04 |
.BR recvmmsg (2),
|
|
Packit |
7cfc04 |
.BR sendmsg (2),
|
|
Packit |
7cfc04 |
.BR socket (2),
|
|
Packit |
7cfc04 |
.BR socket (7)
|
|
Packit |
7cfc04 |
.SH COLOPHON
|
|
Packit |
7cfc04 |
This page is part of release 4.15 of the Linux
|
|
Packit |
7cfc04 |
.I man-pages
|
|
Packit |
7cfc04 |
project.
|
|
Packit |
7cfc04 |
A description of the project,
|
|
Packit |
7cfc04 |
information about reporting bugs,
|
|
Packit |
7cfc04 |
and the latest version of this page,
|
|
Packit |
7cfc04 |
can be found at
|
|
Packit |
7cfc04 |
\%https://www.kernel.org/doc/man\-pages/.
|