Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
539 views
in Technique[技术] by (71.8m points)

c - How sendmsg works?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The manpage speaks of a message (singular) and multiple elements (plural):

For send() and sendto(), the message is found in buf and has length len. For sendmsg(), the message is pointed to by the elements of the array msg.msg_iov. The sendmsg() 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.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...