recv/recvfrom/recvmsg系統調用詳解


【recv/recvfrom/recvmsg系統調用】
功能描述:
從套接字上接收一個消息。對於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索引的不是套接字


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM