recvmsg和sendmsg函数

一、函数原型

#include <sys/socket.h>

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags);

返回:成功返回读入或写入的字节数,出错为-1

二、msghdr结构

struct msghdr {

    void *msg_name;           /* protocol address */
    socklen_t msg_namelen;    /* size of protocol address */
    struct iovec *msg_iov;    /* scatter/gather array */
    int msg_iovlen;           /* # elements in msg_iov */
    void *msg_control;        /* ancillary data (cmsghdr struct) */
    socklen_t msg_controllen; /* length of ancillary data */
    int msg_flags;            /* flags returned by recvmsg */
};

1)msg_name和msg_namelen这两个成员用于套接字未连接的场合(譬如未连接UDP套接字);msg_name指向一个套接字地址结构,调用
者在其中存放接收者(对于sendmsg)或发送者(对于recvmsg)的协议地址;如果无需指明协议地址(譬如对于TCP套接字或已连接UDP
套接字),msg_name应置为空指针;msg_namelen对于sendmsg是一个值参数,对于recvmsg是一个值-结果参数
(2)msg_iov和msg_iovlen这两个成员指定输入或输出缓冲区数组(即iovec结构数组) (3)msg_control和msg_controllen这两个成员指定可选的辅助数据的位置和大小;msg_controllen对于recvmsg是一个值-结果参数

三、关于msg_flags成员

 (1)只有recvmsg使用msg_flags成员;recvmsg被调用时,falgs参数被复制到msg_flags成员,并由内核使用其值驱动接收处理过程;内核

     还依据recvmsg的结果更新msg_flags成员的值;

 (2)sendmsg忽略msg_flags成员,它直接使用flags参数驱动发送处理过程;这意味着如果想在某个sendmsg调用中设置MSG_DONTWAIT

     标志,那就把flags参数设置为该值,把msg_flags成员设置为该值不起作用;

 (3)内核为输入和输出函数检查的flags参数值以及recvmsg可能返回的msg_flags成员值,如下表

             

 (4)recvmsg返回的7个标志解释如下

          

四、调用前后的msghdr结构

 (1)UDP套接字调用recvmsg时

          

 (2)recvmsg返回时

             

五、辅助数据

 (1)辅助数据用途的总结

             

 (2) 辅助数据由一个或多个辅助数据对象构成,每个对象以一个定义在头文件<sys/socket.h>中的cmsghdr结构开头

    struct cmsghdr {
        socklen_t  cmsg_len;     /* length in bytes, including this structure */
        int        cmsg_level;   /* originating protocol */
        int        cmsg_type;    /* protocol-specific type */
    };

 (3)包含两个辅助数据对象的辅助数据

           

 (4)简化辅助数据的五个宏

            

原文地址:https://www.cnblogs.com/soldierback/p/10763937.html