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设置超时时间,但在改时间内没有数据到达
EBADFsocket并非有效的文件描述符
ECONNREFUSED对端主机拒绝了网络连接
EFAULTbuff缓冲区指向非法内存
EINTR在接收数据之前,本次调用被信号中断
EINVAL传递了无效参数
ENOTCONNsocket为面向连接套接字,但我没有成功连接
ENOTSOCKsocketfd用用的并不是一个socket
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值