# sendmmsg

## NAME



           sendmmsg - send multiple messages on a socket
    


## LIBRARY



           Standard C library (_libc_ , _-lc_)
    


## SYNOPSIS



           **#define _GNU_SOURCE** /* See feature_test_macros(7) */
           **#include <sys/socket.h>**
    
           **int sendmmsg(int** _sockfd_**, struct mmsghdr** _msgvec_**[.**_n_**], unsigned int** _n_**,**
                        **int** _flags_**);**
    


## DESCRIPTION



           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 _n_.
    
           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 _n_ messages have been sent.
           A nonblocking call sends as many messages as possible (up to the
           limit specified by _n_) 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.
    


## RETURN VALUE



           On success, **sendmmsg**() returns the number of messages sent from
           _msgvec_ ; if this is less than _n_ , 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.
    


## ERRORS



           Errors are as for sendmsg(2).  An error is returned only if no
           datagrams could be sent.  See also BUGS.
    


## STANDARDS



           Linux.
    


## NOTES



           The value specified in _n_ is capped to **UIO_MAXIOV**(1024).
    


## BUGS



           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.  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.
    


## 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.
    
           #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);
           }
    


* * *