zoukankan      html  css  js  c++  java
  • 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成员中的值,后者计上结尾处可能的填充字节,因而返回的是用于为辅助对象动态分配空间的大小值。

  • 相关阅读:
    21-MySQL-Ubuntu-快速回到SQL语句的行首和行末
    2- SQL语句的强化
    1-数据准备
    20-MySQL-Ubuntu-数据表的查询-子查询(九)
    19-MySQL-Ubuntu-数据表的查询-自关联(八)
    18-MySQL-Ubuntu-数据表的查询-连接(七)
    17-MySQL-Ubuntu-数据表的查询-分页(六)
    16-MySQL-Ubuntu-数据表的查询-分组与聚合(五)
    15-MySQL-Ubuntu-数据表的查询-聚合函数(四)
    14-MySQL-Ubuntu-数据表的查询-范围查询(三)
  • 原文地址:https://www.cnblogs.com/nufangrensheng/p/3607487.html
Copyright © 2011-2022 走看看