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

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

辅助数据由一个或多个辅助数据对象(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个辅助数据对象的一个例子:

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

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

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

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

UNIX网络编程读书笔记:辅助数据的更多相关文章

  1. UNIX网络编程--读书笔记

    会集中这段时间写UNIX网络编程这本书的读书笔记,准备读三本,这一系类的文章会不断更新,一直会持续一个月多,每篇的前半部分是书中讲述的内容,每篇文章的后半部分是自己的心得体会,文章中的红色内容是很重要 ...

  2. UNIX网络编程读书笔记:简介

    认知套接口编程接口 理解原始套接口(raw socket)的概念   值得注意的是,客户和服务器是典型的用户进程,而TCP和IP协议则通常是系统内核协议栈的一部分. 上图中在TCP和UDP之间留有间隙 ...

  3. Unix 网络编程 读书笔记1

    第一章: C/C++语言提供两种不同的编程模式:IPL32和PL64.► IPL32 ● 表示integer/pointer/long三种数据类型是32位(4个字节),在这种模式下,提供32位的地址空 ...

  4. UNIX网络编程读书笔记:原始套接口

    概述 应用程序可以绕过传输层而直接使用IPv4和IPv6,这称为原始套接口(raw socket).http://www.cnblogs.com/nufangrensheng/p/3583435.ht ...

  5. UNIX网络编程读书笔记:套接口选项

    概述 有很多方法来获取和设置影响套接口的选项: getsockopt和setsockopt函数 fcntl函数 ioctl函数 getsockopt和setsockopt函数 这两个函数仅用于套接口. ...

  6. UNIX网络编程读书笔记:UNIX域协议

    概述 UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所用的API(套接口API)相同.UNIX域协议可视为进程间通信 ...

  7. UNIX网络编程读书笔记:I/O模型(阻塞、非阻塞、I/O复用、信号驱动、异步)

    I/O模型 UNIX下可用的5种I/O模型: (1)阻塞I/O (2)非阻塞I/O (3)I/O复用(select和poll) (4)信号驱动I/O(SIGIO) (5)异步I/O 对于一个套接口上的 ...

  8. Unix 网络编程 读书笔记2

    第三章 套接字编程简介 每一个 Socket 都用一个半相关描述:{协议,本地地址,本地端口}一个完整的 Socket 则用一个相关描述{协议,本地地址,本地端口,远程地址,远程端口}每一个 Sock ...

  9. UNIX网络编程读书笔记:基本SCTP套接口编程

    概述 SCTP是一个较新的传输协议,于2000年在IETF得到标准化(TCP是在1981年标准化的).它最初是为满足不断增长的IP电话市场设计的:具体地说,就是穿越因特网传输电话信令. SCTP是一个 ...

随机推荐

  1. 和程序有关的一个游戏<<mu complex>> 攻略

    最速打法: 1 - login, brucedayton 2 - login, allomoto 3 - login, m3g4pa55word 4 - unlock, 03/18/34 5 - ss ...

  2. mac下git+maven+jenkins自动打包发布

    随着springboot+springcloud(dubbo)越来越多人使用,流行的微服务的概念越来越深入人心.分布式部署越来越复杂,给手动发布带来很大工作量.为了方便前期测试和后期线上部署更新,可使 ...

  3. MyBatis连接SQL Server的关键点

    一.Maven包配置 <!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc --> < ...

  4. 【scrapy】使用方法概要(一)(转)

    [请初学者作为参考,不建议高手看这个浪费时间] 工作中经常会有这种需求,需要抓取互联网上的数据.笔者就经常遇到这种需求,一般情况下会临时写个抓取程序,但是每次遇到这种需求的时候,都几乎要重头写,特别是 ...

  5. cuda并行编程之求解ConjugateGradient(共轭梯度迭代)丢失dll解决方式

    在进行图像处理过程中,我们常常会用到梯度迭代求解大型线性方程组.今天在用cuda对神秘矩阵进行求解的时候.出现了缺少dll的情况: 报错例如以下图: watermark/2/text/aHR0cDov ...

  6. 在EntityFramework6中管理DbContext的正确方式——1考虑的关键点(外文翻译)

    (译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gu ...

  7. 国产Linux滋生腐败

    回想过去,2002年12月11日至12日,信息产业部与科技部联合主办"Linux软件与应用猜測研讨会".影响中国IT业的重要人士,包含政府决策者.学界权威.主要Linux推动厂商等 ...

  8. Bootstrap 3之美05-排版、Button、Icon、Nav和NavBar、List、Table、Form

    本篇主要包括: ■  排版■  Button■  Icon■  Nav和NavBar■  List■  Table■  Form 排版 ● 斜体:<em>● 加粗体:<strong& ...

  9. 【docker】关于docker中挂载的解释

    现在有这么一个命令: docker run -p 33061:3306 --name mysql --restart=always -e MYSQL_ROOT_PASSWORD=pisen -v /e ...

  10. Hadoop 组成

    这里介绍一下hadoop的组成, hadoop主要由两部分组成,,一个是hdfs,还有一个是mapreduce 这两个部分在hadoop 2.2.0中分别用start-dfs.sh和start-yar ...