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關聯的緩衝區的size,並在返回時修改為指示實際儲存在那裡的地址大小。

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

廣告


  

廣告



廣告