多進程併發編程----進程間傳遞文件描述符基礎~發送接收附屬數據函數介紹

        如果fork進程之後,子進程如果想要傳遞描述給父進程一般使用socketpair函數。

此篇文章不介紹socketpair函數,二是介紹sendmsg和recvmsg函數,這兩個函數隱藏的機構體有針對socket描述符的選項。

具體如下:

這兩個函數爲程序提供了一些其他的套接口I/O接口所不具備的高級特性。

從概念上說,sendmsg函數是所有寫入函數的基礎,而他是從屬於套接口的。下面的列表以複雜增加的順序列出了所有函數。在每一個層次上,同時列出了所增加的特性。
函數        增加的特性
write        最簡單的套接口寫入函數
send        增加了flags標記
sendto        增加了套接口地址與套接口長度參數
writev        沒有標記與套接口地址,但是具有分散寫入的能力
sendmsg        增加標記,套接口地址與長度,分散寫入以及附屬數據的能力


sendmsg函數

sendmsg函數原型如下:
int sendmsg(int s, const struct msghdr *msg, unsigned int flags);
函數參數描述如下:
要在其上發送消息的套接口s
信息頭結構指針msg,這會控制函數調用的功能
可選的標記位參數flags。這與send或是sendto函數調用的標記參數相同。
函數的返回值爲實際發送的字節數。否則,返回-1表明發生了錯誤,而errno表明錯誤原因。


recvmsg函數
recvmsg是與sendmsg函數相對的函數。這個函數原型如下:
int recvmsg(int s, struct msghdr *msg, unsigned int flags);
函數參數如下:
要在其上接收信息的套接口s
信息頭結構指針msg,這會控制函數調用的操作。
可選標記位參數flags。這與recv或是recvfrom函數調用的標記參數相同。
這個函數的返回值爲實際接收的字節數。否則,返回-1表明發生了錯誤,而errno表明錯誤原因。
理解struct msghdr
當我第一次看到他時,他看上去似乎是一個需要創建的巨大的結構。但是不要怕。其結構定義如下:
struct msghdr {
    void         *msg_name;
    socklen_t    msg_namelen;
    struct iovec *msg_iov;
    size_t       msg_iovlen;
    void         *msg_control;
    size_t       msg_controllen;
    int          msg_flags;
};
結構成員可以分爲四組。他們是:
套接口地址成員msg_name與msg_namelen。
I/O向量引用msg_iov與msg_iovlen。
附屬數據緩衝區成員msg_control與msg_controllen。
接收信息標記位msg_flags。
在我們將這個結構分爲上面的幾類以後,結構看起來就不那樣巨大了。
成員msg_name與msg_namelen
這些成員只有當我們的套接口是一個數據報套接口時才需要。msg_name成員指向我們要發送或是接收信息的套接口地址。成員msg_namelen指明瞭這個套接口地址的長度。
當調用recvmsg時,msg_name會指向一個將要接收的地址的接收區域。當調用sendmsg時,這會指向一個數據報將要發送到的目的地址。
注意,msg_name定義爲一個(void *)數據類型。我們並不需要將我們的套接口地址轉換爲(struct sockaddr *)。
成員msg_iov與msg_iovlen
這些成員指定了我們的I/O向量數組的位置以及他包含多少項。msg_iov成員指向一個struct iovec數組。我們將會回憶起I/O向量指向我們的緩衝區。成員msg_iov指明瞭在我們的I/O向量數組中有多少元素。
成員msg_control與msg_controllen
這些成員指向了我們附屬數據緩衝區並且表明了緩衝區大小。msg_control指向附屬數據緩衝區,而msg_controllen指明瞭緩衝區大小。
成員msg_flags
當使用recvmsg時,這個成員用於接收特定的標記位(他並不用於sendmsg)。在這個位置可以接收的標記位如下表所示:
標記位        描述
MSG_EOR        當接收到記錄結尾時會設置這一位。這通常對於SOCK_SEQPACKET套接口類型十分有用。
MSG_TRUNC    這個標記位表明數據的結尾被截短,因爲接收緩衝區太小不足以接收全部的數據。
MSG_CTRUNC    這個標記位表明某些控制數據(附屬數據)被截短,因爲緩衝區太小。
MSG_OOB        這個標記位表明接收了帶外數據。
MSG_ERRQUEUE    這個標記位表明沒有接收到數據,但是返回一個擴展錯誤。


我們可以man手冊頁中查看更多的信息。


附屬數據結構與宏

recvmsg與sendmsg函數允許程序發送或是接收附屬數據。然而,這些額外的信息受限於一定的格式規則。下一節將會介紹控制信息頭與程序將會用來管理這些信息的宏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章