1 .\" Copyright (c) 2012 by Michael Kerrisk <mtk.manpages@gmail.com>
2 .\" with some material from a draft by
3 .\" Stephan Mueller <stephan.mueller@atsec.com>
4 .\" in turn based on Andi Kleen's recvmmsg.2 page.
6 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
8 .TH sendmmsg 2 (date) "Linux man-pages (unreleased)"
10 sendmmsg \- send multiple messages on a socket
13 .RI ( libc ", " \-lc )
16 .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
17 .B #include <sys/socket.h>
19 .BI "int sendmmsg(int " sockfd ", struct mmsghdr *" msgvec \
20 ", unsigned int " vlen ","
21 .BI " int " flags ");"
26 system call is an extension of
28 that allows the caller to transmit multiple messages on a socket
29 using a single system call.
30 (This has performance benefits for some applications.)
31 .\" See commit 228e548e602061b08ee8e8966f567c12aa079682
35 argument is the file descriptor of the socket
36 on which data is to be transmitted.
40 argument is a pointer to an array of
43 The size of this array is specified in
48 structure is defined in
55 struct msghdr msg_hdr; /* Message header */
56 unsigned int msg_len; /* Number of bytes transmitted */
65 structure, as described in
69 field is used to return the number of bytes sent from the message in
71 (i.e., the same as the return value from a single
77 argument contains flags ORed together.
78 The flags are the same as for
85 messages have been sent.
86 A nonblocking call sends as many messages as possible
87 (up to the limit specified by
89 and returns immediately.
95 fields of successive elements of
97 are updated to contain the number of bytes transmitted from the corresponding
99 The return value of the call indicates the number of elements of
101 that have been updated.
105 returns the number of messages sent from
109 the caller can retry with a further
111 call to send the remaining messages.
113 On error, \-1 is returned, and
115 is set to indicate the error.
119 An error is returned only if no datagrams could be sent.
121 .\" commit 728ffb86f10873aaf4abd26dde691ee40ae731fe
122 .\" ... only return an error if no datagrams could be sent.
123 .\" If less than the requested number of messages were sent, the application
124 .\" must retry starting at the first failed one and if the problem is
125 .\" persistent the error will be returned.
127 .\" This matches the behavior of other syscalls like read/write - it
128 .\" is not an error if less than the requested number of elements are sent.
135 The value specified in
140 .\" commit 98382f419f32d2c12d021943b87dea555677144b
141 .\" net: Cap number of elements for sendmmsg
143 .\" To limit the amount of time we can spend in sendmmsg, cap the
144 .\" number of elements to UIO_MAXIOV (currently 1024).
146 .\" For error handling an application using sendmmsg needs to retry at
147 .\" the first unsent message, so capping is simpler and requires less
148 .\" application logic than returning EINVAL.
150 If an error occurs after at least one message has been sent,
151 the call succeeds, and returns the number of messages sent.
152 The error code is lost.
153 The caller can retry the transmission,
154 starting at the first failed message, but there is no guarantee that,
155 if an error is returned, it will be the same as the one that was lost
156 on the previous call.
158 The example below uses
164 in two distinct UDP datagrams using one system call.
165 The contents of the first datagram originates from a pair of buffers.
167 .\" SRC BEGIN (sendmmsg.c)
170 #include <arpa/inet.h>
171 #include <netinet/in.h>
175 #include <sys/socket.h>
176 #include <sys/types.h>
183 struct iovec msg1[2], msg2;
184 struct mmsghdr msg[2];
185 struct sockaddr_in addr;
187 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
193 addr.sin_family = AF_INET;
194 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
195 addr.sin_port = htons(1234);
196 if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == \-1) {
201 memset(msg1, 0, sizeof(msg1));
202 msg1[0].iov_base = "one";
204 msg1[1].iov_base = "two";
207 memset(&msg2, 0, sizeof(msg2));
208 msg2.iov_base = "three";
211 memset(msg, 0, sizeof(msg));
212 msg[0].msg_hdr.msg_iov = msg1;
213 msg[0].msg_hdr.msg_iovlen = 2;
215 msg[1].msg_hdr.msg_iov = &msg2;
216 msg[1].msg_hdr.msg_iovlen = 1;
218 retval = sendmmsg(sockfd, msg, 2, 0);
220 perror("sendmmsg()");
222 printf("%d messages sent\en", retval);