sendmsg recvmsg函數

sendmsg(2)與recvmsg(2)函數
這些函數爲程序提供了一些其他的套接口I/O接口所不具備的高級特性。下面的內容我們將會先來看一下sendmsg來介紹這些主題。然後將會完整的介紹recvmsg函數,因爲他們的函數接口是相似的。接下來,將會描述msghdr的完整結構。
sendmsg(2)函數
現在是時候進入這個大同盟了。從概念上說,sendmsg函數是所有寫入函數的基礎,而他是從屬於套接口的。下面的列表以複雜增加的順序列出了所有與入函數。在每一個層次上,同時列出了所增加的特性。
函數        增加的特性
write        最簡單的套接口寫入函數
send        增加了flags標記
sendto        增加了套接口地址與套接口長度參數
writev        沒有標記與套接口地址,但是具有分散寫入的能力
sendmsg        增加標記,套接口地址與長度,分散寫入以及附屬數據的能力
sendmsg(2)函數原型如下:
#include 
#include 
int sendmsg(int s, const struct msghdr *msg, unsigned int flags);
函數參數描述如下:
要在其上發送消息的套接口s
信息頭結構指針msg,這會控制函數調用的功能
可選的標記位參數flags。這與send或是sendto函數調用的標記參數相同。
函數的返回值爲實際發送的字節數。否則,返回-1表明發生了錯誤,而errno表明錯誤原因。
recvmsg(2)函數
recvmsg是與sendmsg函數相對的函數。這個函數原型如下:
#include 
#include 
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    這個標記位表明沒有接收到數據,但是返回一個擴展錯誤。
我們可以在recvmsg(2)與sendmsg(2)的man手冊頁中查看更多的信息。
附屬數據結構與宏
recvmsg與sendmsg函數允許程序發送或是接收附屬數據。然而,這些額外的信息受限於一定的格式規則。這一節將會介紹控制信息頭與程序將會用來管理這些信息的宏。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章