As you know sendmsg has this declaration:
int sendmsg(int s, const struct msghdr *msg, int flags);
and msghdr structure has this form:
struct msghdr {
void * msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec * msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void * msg_control; /* ancillary data, see below */
socklen_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
As you see msghdr has an array of buffer, iovec and has buffer count msg_iovlen. What I wonder is that how sendmsg sends these buffers. Does it concatenate all buffers and send or does it send in a for loop?
The sendmsg() function sends messages on a socket with a socket descriptor passed in an array of message headers. Parameter Description socket. The socket descriptor. msg. An array of message headers from which messages are sent.
The system calls send(), sendto(), and sendmsg() are used to transmit a message to another socket. The send() call may be used only when the socket is in a connected state (so that the intended recipient is known). The only difference between send() and write(2) is the presence of flags.
The manpage speaks of a message (singular) and multiple elements (plural):
For
send()
andsendto()
, the message is found inbuf
and has lengthlen
. Forsendmsg()
, the message is pointed to by the elements of the arraymsg.msg_iov
. Thesendmsg()
call also allows sending ancillary data (also known as control information).
For a stream socket, it wouldn't matter either way. Any data you send will just end up as one long stream of data on the other side.
For datagram or message sockets, I can see why a bit more clarity would be helpful. But it appears that you send just one datagram or message with a single sndmsg
call; not one per buffer element.
I actually went digging in the Linux source code out of curiosity and to get a better feeling about this answer. It looks like send
, and sendto
are just wrappers for sendmsg
in Linux, that build the struct msghdr
for you. And in fact, the UDP sendmsg
implementation makes room for one UDP header per sendmsg
call.
If performance is what you're worried about, it doesn't look like you'll benefit from sendmsg
if you pass in just a single iovec
. If you're concatenating buffers in user-space, though, this could potentially win you some.
It's a bit similar to writev
, with the added benefit that you can specify a destination address for use with connectionless sockets like UDP. You can also add ancillary data, if you're into that sort of thing. (Commonly used to send file descriptors across UNIX domain sockets.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With