輔助數(shù)據(jù)(ancillary data)可通過調(diào)用sendmsg和recvmsg這兩個函數(shù),使用msghdr結(jié)構(gòu)中的msg_control和msg_controllen這兩個成員發(fā)送和接收。
輔助數(shù)據(jù)的另一個稱謂是控制信息(control information)。

輔助數(shù)據(jù)由一個或多個輔助數(shù)據(jù)對象(ancillary data object)構(gòu)成,每個對象以一個定義在頭文件<sys/socket.h>中的cmsghdr結(jié)構(gòu)開頭。
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指向的輔助數(shù)據(jù)必須為各個cmsghdr結(jié)構(gòu)適當(dāng)?shù)貙R,如下所示為一種對齊方法:
union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))];}control_un;如下圖所示,展示了在一個控制緩沖區(qū)中出現(xiàn)2個輔助數(shù)據(jù)對象的一個例子:

msg_control指向第一個輔助數(shù)據(jù)對象,輔助數(shù)據(jù)的總長度則由msg_controllen指定。每個對象開頭都是一個描述該對象的cmsghdr結(jié)構(gòu)。在cmsg_type成員和實(shí)際數(shù)據(jù)之間可以有填充字節(jié),從數(shù)據(jù)結(jié)尾處到下一個輔助數(shù)據(jù)對象之前也可以有填充字節(jié)。
注意,不是所有實(shí)現(xiàn)都支持在單個控制緩沖區(qū)中存放多個輔助數(shù)據(jù)對象。
如下圖所示,展示了通過一個UNIX域套接口傳遞描述字或傳遞憑證時所用的cmsghdr結(jié)構(gòu)的格式。

既然由recvmsg返回的輔助數(shù)據(jù)可含有任意數(shù)目的輔助數(shù)據(jù)對象,為了對應(yīng)用程序屏蔽可能出現(xiàn)的填充字節(jié),頭文件<sys/socket.h>中定義了以下5個宏,以簡化對輔助數(shù)據(jù)的處理。
#include <sys/socket.h>#include <sys/param.h> /* for ALIGN macro on many implementations */struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *mhdrptr);返回:指向第一個cmsghdr結(jié)構(gòu)的指針,無輔助數(shù)據(jù)時為NULLstruct cmsghdr *CMSG_NXTHDR(struct msghdr *mhdrptr, struct cmsghdr *cmsgptr);返回:指向下一個cmsghdr結(jié)構(gòu)的指針,不再有輔助數(shù)據(jù)對象時為NULLunsigned char *CMSG_DATA(struct cmsghdr *cmsgptr);返回:指向與cmsghdr結(jié)構(gòu)關(guān)聯(lián)的數(shù)據(jù)的第一個字節(jié)的指針unsigned int CMSG_LEN(unsigned int length);返回:給定數(shù)據(jù)量下存放到cmsg_len中的值unsigned int CMSG_SPACE(unsigned int length);返回:給定數(shù)據(jù)量下一個輔助數(shù)據(jù)對象總的大小
這些宏可以按照如下偽代碼形式使用:
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返回指向第一個輔助數(shù)據(jù)對象的指針,然而如果在msghdr結(jié)構(gòu)中沒有輔助數(shù)據(jù)(或者msg_control為一個空指針,或者cmsg_len小于一個cmsghdr結(jié)構(gòu)的大?。?,那就返回一個空指針。當(dāng)控制緩沖區(qū)中不再有下一個輔助數(shù)據(jù)對象時,CMSG_NXTHDR也返回一個空指針。
CMSG_LEN和CMSG_SPACE的區(qū)別在于,前者不計輔助數(shù)據(jù)對象中數(shù)據(jù)部分之后可能的填充字節(jié),因而返回的是用于存放在cmsg_len成員中的值,后者計上結(jié)尾處可能的填充字節(jié),因而返回的是用于為輔助對象動態(tài)分配空間的大小值。
新聞熱點(diǎn)
疑難解答