簡介struct cmsghdr結構

來源:互聯網
上載者:User


附屬資訊可以包括0,1,或是更多的單獨附屬資料對象。在每一個對象之前都有一個struct
cmsghdr結構。頭部之後是填充位元組,然後是對象本身。最後,附屬資料對象之後,下一個cmsghdr之前也許要有更多的填充位元組。在這一章,我們將
要關注的附屬資料對象是檔案描述符與認證結構。
顯示了一個包含附屬資料的緩衝區是如何組織的。
我們需要注意以下幾點:
cmsg_len與CMSG_LEN()宏值所顯示的長度相同。
CMSG_SPACE()宏可以計算一個附屬資料對象的所必需的空白。
msg_controllen是CMSG_SPACE()長度之後,並且為每一個附屬資料對象進行計算。
控制資訊頭部本身由下面的C結構定義:
struct cmsghdr {
    socklen_t cmsg_len;
    int       cmsg_level;
    int       cmsg_type;
/* u_char     cmsg_data[]; */
};
其成員描述如下:
成員        描述
cmsg_len    附屬資料的位元組計數,這包含結構頭的尺寸。這個值是由CMSG_LEN()宏計算的。
cmsg_level    這個值表明了原始的協議層級(例如,SOL_SOCKET)。
cmsg_type    這個值表明了控制資訊類型(例如,SCM_RIGHTS)。
cmsg_data    這個成員並不實際存在。他用來指明實際的額外附屬資料所在的位置。
這一章所用的例子程式只使用SOL_SOCKET的cmsg_level值。這一章我們感興趣的控制資訊類型如下(cmsg_level=SOL_SOCKET):
cmsg_level        描述
SCM_RIGHTS        附屬資料對象是一個檔案描述符
SCM_CREDENTIALS        附屬資料對象是一個包含認證資訊的結構
簡介cmsg(3)宏
由於附屬資料結構的複雜性,Linux系統提供了一系列的C宏來簡化我們的工作。另外,這些宏可以在不同的UNIX平台之間進行移植,並且採取了一些措施來防止將來的改變。這些宏是由cmsg(3)的man手冊頁來進行描述的,其概要如下:
#include 
struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh, struct cmsghdr *cmsg);
size_t CMSG_ALIGN(size_t length);
size_t CMSG_SPACE(size_t length);
size_t CMSG_LEN(size_t length);
void *CMSG_DATA(struct cmsghdr *cmsg);
CMSG_LEN()宏
這個宏接受我們希望放置在附屬資料緩衝區中的對象尺寸作為輸入參數。如果我們回顧一個我們前面的介紹,我們就會發現這個宏會計算cmsghdr頭結構加上所需要的填充字元的位元組長度。這個值用來設定cmsghdr對象的cmsg_len成員。
下面的例子示範了如果附屬資料是一個檔案描述符,我們應如何來計算cmsg_len成員的值:
int fd;   /* File descriptor */
printf("cmsg_len = %d/n",CMSG_LEN(sizeof fd));
CMSG_SPACE()宏
這個宏用來計算附屬資料以及其頭部所需的總空白。儘管CMSG_LEN()宏計算了一個相似的長度,CMSG_LEN()值並不包括可能的結尾的填充字元。CMSG_SPACE()宏對於確定所需的緩衝區尺寸是十分有用的,如下面的範例程式碼所示:
int fd; /* File Descriptor */
char abuf[CMSG_SPACE(sizeof fd)];
這個例子在abuf[]中聲明了足夠的緩衝區空間來存放頭部,填充位元組以及附屬資料本身,和最後的填充位元組。如果在緩衝區中有多個附屬資料對象,一定要同時添加多個CMSG_SPACE()宏調用來得到所需的總空間。
CMSG_DATA()宏
這個宏接受一個指向cmsghdr結構的指標。返回的指標值指向跟隨在頭部以及填充位元組之後的附屬資料的第一個位元組(如果存在)。如果指標mptr指向一個描述檔案描述符的可用的附屬資料資訊頭部,這個檔案描述符可以用下面的代碼來得到:
struct cmsgptr *mptr;
int fd; /* File Descriptor */
. . .
fd = *(int *)CMSG_DATA(mptr);
CMSG_ALIGN()宏
這是一個Linux擴充宏,而不是Posix.1g標準的一部分。指定一個位元組長度作為輸入,這個宏會計算一個新的長度,這個新長度包括為了維護對齊所需要的額外的填充位元組。
CMSG_FIRSTHDR()宏

個宏用於返回一個指向附屬資料緩衝區內的第一個附屬對象的struct cmsghdr指標。輸入值為是指向struct
msghdr結構的指標(不要與struct
cmsghdr相混淆)。這個宏會估計msghdr的成員msg_control與msg_controllen來確定在緩衝區中是否存在附屬對象。然
後,他會計算返回的指標。
如果不存在附屬資料對象則返回的指標值為NULL。否則,這個指標會指向存在的第一個struct cmsghdr。這個宏用在一個for迴圈的開始處,來開始在附屬資料對象中遍曆。
CMSG_NXTHDR()宏
這個用於返回下一個附屬資料對象的struct cmsghdr指標。這個宏會接受兩個輸入參數:
指向struct msghdr結構的指標
指向當前struct cmsghdr的指標
如果沒有下一個附屬資料對象,這個宏就會返回NULL。
遍曆附屬資料
當接收到一個附屬資料時,我們可以使用CMSG_FIRSTHDR()與CMSG_NXTHDR()宏來在附屬資料對象中進行遍曆。下面的範例程式碼顯示了for迴圈的通常格式以及宏的相應用法:
struct msghdr msgh;     /* Message Hdr */
struct cmsghdr *cmsg;0   /*Ptr to ancillary hdr */
int *fd_ptr;            /* Ptr to file descript.*/
int received_fd;        /* The file descriptor */
for ( cmsg=CMSG_FIRSTHDR(&msgh); cmsg!=NULL; cmsg=CMSG_NXTHDR(&msgh,cmsg) ) {
    if ( cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS ) {
        fd_ptr = (int *) CMSG_DATA(cmsg);
        received_fd = *fd_ptr;
        break;
    }
}
if ( cmsg == NULL ) {
    /* Error: No file descriptor recv'd */
}
建立附屬資料
要發送一個檔案描述符的進程必須使用正確的格式化資料來建立一個附屬資料緩衝區。下面的代碼展示的通常的建立過程:
struct msghdr msg;            /* Message header */
struct cmsghdr *cmsg; /* Ptr to ancillary hdr */
int fd;              /* File descriptor to send */
char buf[CMSG_SPACE(sizeof fd)]; /* Anc. buf */
int *fd_ptr;           /* Ptr to file descriptor */
msg.msg_control = buf;
msg.msg_controllen = sizeof buf;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof fd);
/* Initialize the payload: */
fd_ptr = (int *)CMSG_DATA(cmsg);
*fd_ptr = fd;
/*
* Sum of the length of all control
* messages in the buffer:
*/
msg.msg_controllen = cmsg->cmsg_len;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.