sendmmsg(2)
π sendmmsg(2) β the socket girlies' group send π
okay bestie, listen. this is a Linux system call manual page, and today we're talking about sendmmsg(2) β that's section 2 of the manual, the system calls section. pull up a chair, grab a strawberry, and let's get into it β¨
πΈ NAME πΈ
sendmmsg β send multiple messages on a socket. yes queen, multiple. one syscall. many messages. it's giving efficiency π
π LIBRARY π
Standard C library β that's libc, and you link it with -lc. she's standard, she's everywhere, she's iconic π
β¨ SYNOPSIS β¨
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sys/socket.h>
int sendmmsg(unsigned int n;
int sockfd, struct mmsghdr msgvec[n], unsigned int n,
int flags);
so first things first: you need that #define _GNU_SOURCE before your includes, bestie. it's the magic passphrase, and the feature_test_macros(7) page will tell you all about why. then you pull in <sys/socket.h> like a good girl and you're ready to go π¦
π DESCRIPTION π
The sendmmsg() system call is literally an extension of sendmsg(2) β same energy, but it lets you transmit multiple messages on a socket with a single system call. not me sending a whole thread in one go π This has performance benefits for some applications. slay.
The sockfd argument is the file descriptor of the socket where your data is being transmitted. like, the actual socket identity. yes.
The msgvec argument is a pointer to an array of mmsghdr structures. the size of that array? that's what you're telling it in n.
now the mmsghdr structure β it's defined in <sys/socket.h> and she looks like this:
struct mmsghdr {
struct msghdr msg_hdr; /* Message header */
unsigned int msg_len; /* Number of bytes transmitted */
};
the msg_hdr field is a msghdr structure, exactly as described over in sendmsg(2). the msg_len field is the return-value girlie: it's used to return the number of bytes sent from the message in msg_hdr β i.e., the same as what a single sendmsg(2) call would give you back. same value, different font π
The flags argument contains flags ORed together. The flags are the same as for sendmsg(2). no new flags, don't get creative.
so like, a blocking sendmmsg() call blocks until n messages have been sent. a nonblocking call sends as many messages as possible (up to the limit specified by n) and returns immediately. she doesn't wait around π
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. and the return value of the call tells you the number of elements of msgvec that have been updated. so you always know how far you got. obsessed.
π«Ά RETURN VALUE π«Ά
On success, sendmmsg() returns the number of messages sent from msgvec. and if that number is less than n, bestie you can retry with a further sendmmsg() call to send the remaining messages. it's giving "we go again" π
On error, -1 is returned, and errno is set to indicate the error. classic. the -1 jumpscare π
π ERRORS π
Errors are as for sendmsg(2). and this is the important part: an error is returned only if no datagrams could be sent. if even one got out the door, you're getting a success. See also BUGS β and yes, you should genuinely go read BUGS, it's right below and it's messy π
π STANDARDS π
Linux. just Linux, babes. that's the whole standard. periodt.
π HISTORY π
Linux 3.0, glibc 2.14. old enough to have a driver's license, still serving.
β NOTES β
The value specified in n is capped to UIO_MAXIOV (1024). so if you roll up with a bigger n than that, it gets trimmed, no cap. well. cap. you know what I mean π
π BUGS π
okay this one is the real one, pay attention, don't scroll past it.
If an error occurs after at least one message has been sent, the call succeeds, and returns the number of messages sent. The error code is lost. gone. evaporated. not coming back π«
The caller can retry the transmission, starting at the first failed message, but there is no guarantee that, if an error is returned, it will be the same as the one that was lost on the previous call. so you might get a different error than the one that ghosted you before. tragic. no cap.
π§ EXAMPLES π§
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. look at her go π
#define _GNU_SOURCE
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
int
main(void)
{
int retval;
int sockfd;
struct iovec msg1[2], msg2;
struct mmsghdr msg[2];
struct sockaddr_in addr;
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);
}
π₯ SEE ALSO π₯
and that's the whole page, bestie π«Ά this one came from Linux man-pages 6.20, dated 2026-02-08, and the page itself was sendmmsg(2) from the System Calls Manual. go forth and batch your datagrams responsibly, iykyk π
β¨
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: Linux-man-pages-copyleft
- Copyright 2012, Michael Kerrisk <mtk.manpages@gmail.com>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms