Linux系統調用-- recv/recvfrom/recvmsg函數詳解

轉自:http://club.cn.yahoo.com/bbs/threadview/1200062866_65__pn.html 

功能描述: 
從套接字上接收一個消息。對於recvfrom 和 recvmsg,可同時應用於面向連接的和無連接的套接字。recv一般只用在面向連接的套接字,幾乎等同於recvfrom,只要將recvfrom的第五個參數設置NULL。
如果消息太大,無法完整存放在所提供的緩衝區,根據不同的套接字,多餘的字節會丟棄。
假如套接字上沒有消息可以讀取,除了套接字已被設置爲非阻塞模式,否則接收調用會等待消息的到來。

用法: 
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sock, void *buf, size_t len, int flags);
ssize_t recvfrom(int sock, void *buf, size_t len, int flags, 
     struct sockaddr *from, socklen_t *fromlen);
ssize_t recvmsg(int sock, struct msghdr *msg, int flags);
參數:   
sock:索引將要從其接收數據的套接字。
buf:存放消息接收後的緩衝區。
len:buf所指緩衝區的容量。
flags:是以下一個或者多個標誌的組合體,可通過or操作連在一起
MSG_DONTWAIT:操作不會被阻塞。
MSG_ERRQUEUE: 指示應該從套接字的錯誤隊列上接收錯誤值,依據不同的協議,錯誤值以某種輔佐性消息的方式傳遞進來, 使用者應該提供足夠大的緩衝區。導致錯誤的原封包通過msg_iovec作爲一般的數據來傳遞。導致錯誤的數據報原目標地址作爲msg_name被提供。 錯誤以sock_extended_err結構形態被使用,定義如下
#define SO_EE_ORIGIN_NONE    0
#define SO_EE_ORIGIN_LOCAL   1
#define SO_EE_ORIGIN_ICMP    2
#define SO_EE_ORIGIN_ICMP6   3
struct sock_extended_err
{
    u_int32_t ee_errno;   /* error number */
    u_int8_t ee_origin; /* where the error originated */
    u_int8_t ee_type;    /* type */
    u_int8_t ee_code;    /* code */
    u_int8_t ee_pad;
    u_int32_t ee_info;    /* additional information */
    u_int32_t ee_data;    /* other data */
    /* More data may follow */
};
MSG_PEEK:指示數據接收後,在接收隊列中保留原數據,不將其刪除,隨後的讀操作還可以接收相同的數據。
MSG_TRUNC:返回封包的實際長度,即使它比所提供的緩衝區更長, 只對packet套接字有效。 
MSG_WAITALL:要求阻塞操作,直到請求得到完整的滿足。然而,如果捕捉到信號,錯誤或者連接斷開發生,或者下次被接收的數據類型不同,仍會返回少於請求量的數據。
MSG_EOR:指示記錄的結束,返回的數據完成一個記錄。
MSG_TRUNC:指明數據報尾部數據已被丟棄,因爲它比所提供的緩衝區需要更多的空間。
MSG_CTRUNC:指明由於緩衝區空間不足,一些控制數據已被丟棄。
MSG_OOB:指示接收到out-of-band數據(即需要優先處理的數據)。
MSG_ERRQUEUE:指示除了來自套接字錯誤隊列的錯誤外,沒有接收到其它數據。
from:指向存放對端地址的區域,如果爲NULL,不儲存對端地址。
fromlen:作爲入口參數,指向存放表示from最大容量的內存單元。作爲出口參數,指向存放表示from實際長度的內存單元。
msg:指向存放進入消息頭的內存緩衝,結構形態如下
struct msghdr {
    void         *msg_name;       /* optional address */
    socklen_t     msg_namelen;    /* size of address */
    struct iovec *msg_iov;        /* scatter/gather array */
    size_t        msg_iovlen;     /* # elements in msg_iov */
    void         *msg_control;    /* ancillary data, see below */
    socklen_t     msg_controllen; /* ancillary data buffer len */
    int           msg_flags;      /* flags on received message */
};

可能用到的數據結構有
struct cmsghdr {
    socklen_t cmsg_len;     /* data byte count, including hdr */
    int       cmsg_level;   /* originating protocol */
    int       cmsg_type;    /* protocol-specific type */
    /* followed by
    u_char    cmsg_data[]; */
};

返回說明:   
成功執行時,返回接收到的字節數。另一端已關閉則返回0。失敗返回-1,errno被設爲以下的某個值   
EAGAIN:套接字已標記爲非阻塞,而接收操作被阻塞或者接收超時
EBADF:sock不是有效的描述詞
ECONNREFUSE:遠程主機阻絕網絡連接
EFAULT:內存空間訪問出錯
EINTR:操作被信號中斷
EINVAL:參數無效
ENOMEM:內存不足
ENOTCONN:與面向連接關聯的套接字尚未被連接上
ENOTSOCK:sock索引的不是套接字
發佈了10 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章