• UNIX网络编程读书笔记:辅助数据


    辅助数据(ancillary data)可通过调用sendmsg和recvmsg这两个函数,使用msghdr结构中的msg_control和msg_controllen这两个成员发送和接收。

    辅助数据的另一个称谓是控制信息(control information)。

    image

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

    struct cmsghdr {
        socketlen_t    cmsg_len;      /* length in bytes, including this structure */
        int            cmsg_level;    /* originating protocol */
        int            cmsg_type;     /* protocol-specific type */
        /* followed by unsigned char msg_data[] */
    };

    由msg_control指向的辅助数据必须为各个cmsghdr结构适当地对齐,如下所示为一种对齐方法:

    union {
              struct cmsghdr     cm;
              char               control[CMSG_SPACE(sizeof(int))];
    }control_un;

    如下图所示,展示了在一个控制缓冲区中出现2个辅助数据对象的一个例子:

    image

    msg_control指向第一个辅助数据对象,辅助数据的总长度则由msg_controllen指定。每个对象开头都是一个描述该对象的cmsghdr结构。在cmsg_type成员和实际数据之间可以有填充字节,从数据结尾处到下一个辅助数据对象之前也可以有填充字节。

    注意,不是所有实现都支持在单个控制缓冲区中存放多个辅助数据对象。

    如下图所示,展示了通过一个UNIX域套接口传递描述字或传递凭证时所用的cmsghdr结构的格式。

    image

    既然由recvmsg返回的辅助数据可含有任意数目的辅助数据对象,为了对应用程序屏蔽可能出现的填充字节,头文件<sys/socket.h>中定义了以下5个宏,以简化对辅助数据的处理。

    #include <sys/socket.h>
    #include <sys/param.h>    /* for ALIGN macro on many implementations */
    
    struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *mhdrptr);
    返回:指向第一个cmsghdr结构的指针,无辅助数据时为NULL
    
    struct cmsghdr *CMSG_NXTHDR(struct msghdr *mhdrptr, struct cmsghdr *cmsgptr);
    返回:指向下一个cmsghdr结构的指针,不再有辅助数据对象时为NULL
    
    unsigned char *CMSG_DATA(struct cmsghdr *cmsgptr);
    返回:指向与cmsghdr结构关联的数据的第一个字节的指针
    
    unsigned int CMSG_LEN(unsigned int length);
    返回:给定数据量下存放到cmsg_len中的值
    
    unsigned int CMSG_SPACE(unsigned int length);
    返回:给定数据量下一个辅助数据对象总的大小

    这些宏可以按照如下伪代码形式使用:

    struct msghdr    msg;
    struct cmsghdr    *cmsgptr;
    /* fill in msg structure */
    /* call recvmsg() */
    for(cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
    {
        if(cmsgptr->cmsg_level == ... && cmsgptr->cmsg_type == ...)
        {
            u_char    *ptr;
            
            ptr = CMSG_DATA(cmsgptr);
            /* process data pointed to by ptr */
        }
    }

    CMSG_FIRSTHDR返回指向第一个辅助数据对象的指针,然而如果在msghdr结构中没有辅助数据(或者msg_control为一个空指针,或者cmsg_len小于一个cmsghdr结构的大小),那就返回一个空指针。当控制缓冲区中不再有下一个辅助数据对象时,CMSG_NXTHDR也返回一个空指针。

    CMSG_LEN和CMSG_SPACE的区别在于,前者不计辅助数据对象中数据部分之后可能的填充字节,因而返回的是用于存放在cmsg_len成员中的值,后者计上结尾处可能的填充字节,因而返回的是用于为辅助对象动态分配空间的大小值。

  • 相关阅读:
    NSObject-拷贝 NSCopy-NSMutablecopy
    NSObject 排序
    iOS UIView上添加mp4视频
    OC语言中BOOL 和 bool 区别
    便利初始化浅析
    可变字符与不可不可变字符串的心得
    博客开通随笔
    OC总结第五讲:多态
    oc总结第四讲:属性
    oc总结第三讲 setter getter 方法 点运算符
  • 原文地址:https://www.cnblogs.com/nufangrensheng/p/3607487.html
Copyright © 2020-2023  润新知