天天看點

socket程式設計之recv()函數族

7.recv()函數族

7.1 包含頭檔案

#include <sys/types.h>
#include <sys/socket.h>		
           

7.2 函數主體

1. ssize_t recv(int sockfd, void *buf, size_t len, int flags);
2. ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
3. ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
           

參數解釋:

  • int sockfd

​ 該參數指明從檔案描述符fd的緩沖區讀取資料。

  • void *buf

​ recv()函數簇讀到的資料将儲存到buf所指向的空間中,用法和read()同理。

  • size_t len

​ 該參數指明本次調用接收資料的最大長度。

  • int flags

​ 如果flags設定為0,那麼recv()函數和read()沒有任何差別。flags還可以通過OR設定如下參數:

标志位 解釋
MSG_CMSG_CLOEXEC (僅限recvmsg()) 此flag使用原因通open()中的O_CLOEXEC flag,再socket()中也有介紹,此處不再贅述
MSG_DONTWAIT 設定本次調用為非阻塞,與O_NONBLOCK flag類似,但是該标志為作用域僅限于本次recv調用,而後者則是對檔案描述符操作。
MSG_OOB 此标志指定在正常資料流的接受中不會接收帶外資料。某些協定将加急資料放在正常資料隊列的頭部,是以此标志不能與此類協定一起使用。
MSG_PEEK 此标志指定從接收隊列接收資料,但是不從删除隊列中删除這些資料
MSG_TRUNC 傳回資料報(udp)的實際長度,即使它比傳遞的就收緩沖區更長。注意預設情況下,資料包報無法放入緩沖區時,recv調用會丢棄多餘的位元組
MSG_WAITALL 此标志請求操作阻塞,直到滿足收到的資料滿足請求。 但是,如果信号被捕獲、發生錯誤或斷開連接配接,或者要接收的下一個資料的類型與傳回的資料類型不同,則調用傳回的資料可能仍少于請求的資料。 此标志對資料報套接字沒有影響。
  • *struct sockaddr src_addr

​ 如果src_addr非NULL,且協定提供消息的源位址,則該源位址将放在 src_addr 所指向的緩沖區中。

  • *socklen_t addrlen

    addrlen 是一個value-result參數。在調用之前,應将其初始化為與src_addr關聯的緩沖區的大小。傳回後,addrlen 将更新為包含源位址的實際大小。 如果提供的緩沖區太小,則傳回的位址将被截斷;在這種情況下,addrlen 将傳回一個大于提供給調用的值。

    如果不需要知道源位址,則可以将src_addr和addrlen均設為NULL即可。

  • struct msghdr *msg
//該結構體如下,等用到時,在進行補充
  struct iovec {                    /* Scatter/gather array items */
               void  *iov_base;              /* Starting address */
               size_t iov_len;               /* Number of bytes to transfer */
           };
 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 */
               size_t        msg_controllen; /* ancillary data buffer len */
               int           msg_flags;      /* flags on received message */
           };
           

7.3 傳回值

這些調用傳回收到的位元組數,如果發生錯誤,則傳回 -1。 如果發生錯誤,設定了 errno 用來訓示錯誤。當對端為流套接字且執行關閉函數時,傳回值為0,表示連接配接正常關閉;當對端為流\域套接字時,允許收到是長度為0的資料報。錯誤類型如下(隻列出socket層産生的錯誤,更底層(傳輸層及以下)的錯誤再前面文章種已經全部列出):

錯誤類型 解釋
EAGAIN or EWOULDBLOCK 設定逾時時間,但在改時間内沒有資料到達
EBADF socket并非有效的檔案描述符
ECONNREFUSED 對端主機拒絕了網絡連接配接
EFAULT buff緩沖區指向非法記憶體
EINTR 在接收資料之前,本次調用被信号中斷
EINVAL 傳遞了無效參數
ENOTCONN socket為面向連接配接套接字,但我沒有成功連接配接
ENOTSOCK socketfd用用的并不是一個socket

繼續閱讀