`
阅读更多
        辅助数据(ancillary data)也称控制信息(control information)。在recv/send 和 recvmsg/sendmsg 函数一节中介绍 sendmsg 和 recvmsg 函数时提到,可以使用 msghdr 结构中的 msg_control 和 msg_controllen 成员来发送和接收辅助数据。
        下表总结了辅助数据的主要用途。

        辅助数据是由一个或多个辅助数据对象(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 个辅助数据对象的例子(不是所有实现都支持在单个控制缓冲区中存放多个辅助数据对象)。

        这里,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 */
    }
}

  • 大小: 36.6 KB
  • 大小: 23.3 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics