欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

辅助数据

程序员文章站 2022-07-12 16:49:29
...
        辅助数据(ancillary data)也称控制信息(control information)。在recv/send 和 recvmsg/sendmsg 函数一节中介绍 sendmsg 和 recvmsg 函数时提到,可以使用 msghdr 结构中的 msg_control 和 msg_controllen 成员来发送和接收辅助数据。
        下表总结了辅助数据的主要用途。
辅助数据
            
    
    博客分类: 网络编程 计算机网络sendmsgrecvmsgmsghdrcmsghdr 
        辅助数据是由一个或多个辅助数据对象(ancillary data object)构成,每个对象都以一个 cmsghdr 结构开头。
#include <sys/socket.h>

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

        由 msg_control 指向的辅助数据必须为 cmsghdr 结构适当地对齐。下图展示了在一个控制缓冲区中出现 2 个辅助数据对象的例子(不是所有实现都支持在单个控制缓冲区中存放多个辅助数据对象)。
辅助数据
            
    
    博客分类: 网络编程 计算机网络sendmsgrecvmsgmsghdrcmsghdr 
        这里,msg_control 指向第一个辅助数据对象,msg_controllen 表示辅助数据的总长度。每个对象开头都是一个描述该对象的 cmsghdr 结构。在 cmsg_type 成员和实际数据之间可以有填充字节,从数据结尾处到下一个辅助数据对象之前也可以有填充字节。
        为简化对辅助数据的处理,可以使用以下的 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);
      /* 返回值:给定数据量下一个辅助数据对象总的大小 */

        这里需要注意的是,CMSG_FIRSTHDR 会在 msghdr 结构中没有辅助数据,或者 msg_control 为一个空指针,或者 cmsg_len 小于一个 cmsghdr 结构的大小时返回一个空指针。此外,CMSG_FIRSTHDR 宏的许多现有实现并不检查 msg_controllen 而直接返回 cmsg_control 的值,为保险起见,最好在调用该宏之前测试 msg_controllen 的值。
        CMSG_LEN 和 CMSG_SPACE 的区别在于,前者不计算辅助数据对象中数据部分后可能的填充字节,因而返回的是用于存放在 cmsg_len 成员中的值,后者则会加上结尾处可能的填充字节,因此返回的是为辅助数据对象动态分配空间的大小值。
        这几个宏可以如下形式的伪代码使用。
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 = CMSG_DATA(cmsgptr);
        /* process data pointed to by ptr */
    }
}

  • 辅助数据
            
    
    博客分类: 网络编程 计算机网络sendmsgrecvmsgmsghdrcmsghdr 
  • 大小: 36.6 KB
  • 辅助数据
            
    
    博客分类: 网络编程 计算机网络sendmsgrecvmsgmsghdrcmsghdr 
  • 大小: 23.3 KB