recv() - Unix 和 Linux 系統呼叫 - 技術教學
Tutorials Point


  Unix 初學者指南
  Unix Shell 程式設計
  高階 Unix
  Unix 有用參考
  Unix 有用資源
  精選閱讀

版權所有 © 2014 tutorialspoint



  首頁     參考     討論論壇     關於TP  

recv() - Unix 和 Linux 系統呼叫


previous next AddThis Social Bookmark Button

廣告

名稱

recv、recvfrom、recvmsg - 從套接字接收訊息

語法

#include <sys/types.h> 

#include <sys/socket.h>

ssize_t recv(int s, void *buf, size_t len, int flags);

ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

ssize_t recvmsg(int s, struct msghdr *msg, int flags);

描述

recvfrom() 和 recvmsg() 呼叫用於從套接字接收訊息,無論套接字是否面向連線,都可以用於接收套接字上的資料。

如果from不為 NULL,並且底層協議提供源地址,則填充此源地址。引數fromlen是一個值-結果引數,初始化為與from關聯的緩衝區的尺寸,並在返回時修改以指示儲存在其中的地址的實際尺寸。

recv() 呼叫通常僅用於已連線的套接字(參見connect(2)),並且與from引數為 NULL 的recvfrom() 相同。

所有三個例程在成功完成時都返回訊息的長度。如果訊息太長而無法放入提供的緩衝區中,則根據接收訊息的套接字型別,可能會丟棄多餘的位元組。

如果套接字上沒有可用訊息,則接收呼叫會等待訊息到達,除非套接字是非阻塞的(參見fcntl(2)),在這種情況下,將返回-1 並且外部變數errno設定為EAGAIN。接收呼叫通常返回任何可用資料,最多請求的數量,而不是等待接收請求的全部數量。

select(2) 或poll(2) 呼叫可用於確定何時到達更多資料。

recv() 呼叫的flags引數是透過OR以下一個或多個值形成的

標籤描述
MSG_DONTWAIT
 啟用非阻塞操作;如果操作將阻塞,則返回EAGAIN(這也可以使用O_NONBLOCKF_SETFL fcntl(2)一起啟用)。
MSG_ERRQUEUE
 此標誌指定應從套接字錯誤佇列接收排隊的錯誤。錯誤以輔助訊息傳遞,其型別取決於協議(對於 IPv4 IP_RECVERR)。使用者應提供足夠大小的緩衝區。有關更多資訊,請參見cmsg(3) 和ip(7)。導致錯誤的原始資料包的有效負載透過msg_iovec作為普通資料傳遞。導致錯誤的資料報的原始目標地址透過msg_name提供。
對於本地錯誤,不會傳遞地址(這可以使用cmsghdrcmsg_len成員進行檢查)。對於錯誤接收,MSG_ERRQUEUEmsghdr中設定。在錯誤傳遞後,將根據下一個排隊的錯誤重新生成掛起的套接字錯誤,並在下一個套接字操作上傳遞。

錯誤以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 */ };

struct sockaddr *SO_EE_OFFENDER(struct sock_extended_err *);

ee_errno包含排隊錯誤的 errno 編號。ee_origin是錯誤原始碼。其他欄位是特定於協議的。宏SOCK_EE_OFFENDER返回一個指向錯誤源網路物件的地址的指標,該指標給出了指向輔助訊息的指標。如果不知道此地址,則sockaddrsa_family成員包含AF_UNSPEC,並且sockaddr的其他欄位未定義。導致錯誤的資料包的有效負載作為普通資料傳遞。
對於本地錯誤,不會傳遞地址(這可以使用cmsghdrcmsg_len成員進行檢查)。對於錯誤接收,MSG_ERRQUEUEmsghdr中設定。在錯誤傳遞後,將根據下一個排隊的錯誤重新生成掛起的套接字錯誤,並在下一個套接字操作上傳遞。
MSG_OOB
 此標誌請求接收帶外資料,這些資料不會在正常資料流中接收。某些協議將加速資料放在正常資料佇列的開頭,因此此標誌不能與此類協議一起使用。
MSG_PEEK
 此標誌導致接收操作從接收佇列的開頭返回資料,而不會從佇列中刪除該資料。因此,後續接收呼叫將返回相同的資料。
MSG_TRUNC
 返回資料包的實際長度,即使它長於傳遞的緩衝區。僅對資料包套接字有效。
MSG_WAITALL
 此標誌請求操作阻塞,直到完全滿足請求。但是,如果捕獲到訊號、發生錯誤或斷開連線,或者要接收的下一個資料與返回的資料型別不同,則呼叫仍可能返回少於請求的資料。
recvmsg() 呼叫使用msghdr結構來最大程度地減少直接提供的引數數量。此結構具有以下形式,如<sys/socket.h>中定義

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 */ };

這裡msg_namemsg_namelen指定源地址(如果套接字未連線);如果不需要或不需要名稱,則可以將msg_name指定為 null 指標。欄位msg_iovmsg_iovlen描述散佈-收集位置,如readv(2)中所述。欄位msg_control(長度為msg_controllen)指向用於其他協議控制相關訊息或雜項輔助資料的緩衝區。呼叫recvmsg() 時,msg_controllen應包含msg_control中可用緩衝區的長度;在成功呼叫返回後,它將包含控制訊息序列的長度。
訊息的格式為

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[]; */ };

輔助資料應僅由cmsg(3)中定義的宏訪問。
例如,Linux 使用此輔助資料機制透過 Unix 套接字傳遞擴充套件錯誤、IP 選項或檔案描述符。
recvmsg() 返回後,將設定msghdr中的msg_flags欄位。它可以包含多個標誌
MSG_EOR
 指示記錄結束;返回的資料已完成記錄(通常與型別為SOCK_SEQPACKET的套接字一起使用)。
MSG_TRUNC
 指示由於資料報大於提供的緩衝區而丟棄了資料報的尾部。
MSG_CTRUNC
 指示由於輔助資料緩衝區空間不足而丟棄了一些控制資料。
MSG_OOB
 返回以指示已接收加速或帶外資料。
MSG_ERRQUEUE
 指示未接收任何資料,但來自套接字錯誤佇列的擴充套件錯誤。

返回值

這些呼叫返回接收到的位元組數,如果發生錯誤則返回-1。當對等方已執行有序關閉時,返回值將為 0。

錯誤

這些是由套接字層生成的一些標準錯誤。其他錯誤可能會由底層協議模組生成並返回;請參閱其手冊頁。
標籤描述
EAGAIN 套接字標記為非阻塞且接收操作將阻塞,或者已設定接收超時並且在接收資料之前超時已過期。
EBADF 引數s是無效描述符。
ECONNREFUSED
 遠端主機拒絕允許網路連線(通常是因為它未執行請求的服務)。
EFAULT 接收緩衝區指標指向程序地址空間之外。
EINTR 在任何資料可用之前,接收被訊號傳遞中斷。
EINVAL 傳遞了無效引數。
ENOMEM 無法為recvmsg()分配記憶體。
ENOTCONN
 套接字與面向連線的協議關聯,並且尚未連線(參見connect(2) 和accept(2))。
ENOTSOCK
 引數s不引用套接字。

符合標準

4.4BSD(這些函式呼叫首次出現在 4.2BSD 中),POSIX.1-2001。

POSIX.1-2001 僅描述MSG_OOBMSG_PEEKMSG_WAITALL標誌。

備註

上面給出的原型遵循 glibc2。Single Unix Specification 也是如此,除了它的返回值型別為“ssize_t”(而 4.x BSD 和 libc4 和 libc5 都為“int”)。flags引數在 4.x BSD 中為“int”,但在 libc4 和 libc5 中為“unsigned int”。len引數在 4.x BSD 中為“int”,但在 libc4 和 libc5 中為“size_t”。fromlen引數在 4.x BSD、libc4 和 libc5 中為“int *”。當前的“socklen_t *”是由 POSIX 發明的。另請參見accept(2)。

根據 POSIX.1-2001,msghdr結構的msg_controllen欄位應型別化為socklen_t,但 glibc 當前(2.4)將其型別化為size_t

參見



previous next Printer Friendly

廣告


  

廣告



廣告
© . All rights reserved.