Linux网络编程之recv函数

功能

recv 函数的功能就是从套接字中接收数据。

头文件

#include 
#include 

原型

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

参数

参数 描述
sockfd socket 文件描述符
buf 接收数据缓冲区
len 接收数据缓冲区的大小
flags 标志,一般置0,若需要设置多个标志,则通过 “或” 逻辑进行连接

flags 可以设置为如下几种:

flags 标志
MSG_CMSG_CLOEXEC
MSG_DONTWAIT
MSG_ERRQUEUE
MSG_OOB
MSG_PEEK
MSG_TRUNC
MSG_WAITALL

返回值

  • 成功:接收到的字节数
  • 失败:-1,并设置 errno
  • 其他:当出现如下情况时,返回0
    • 当流套接字(socket 函数中参数 type = SOCK_STREAM)对端关闭连接时,返回值将为0;
    • UNIX 和 Internet 域数据报套接字允许长度为0的数据报。当接收到这样的数据报时,返回值为0;
    • 当流套接字对端发送长度为0的数据段,也可以返回值0。

errno 的值可能是:

错误值 解释
EAGAIN(11) 套接字已标记为非阻塞,调用 recv 读取数据而此时没有数据可读,则返回该错误
EWOULDBLOCK 含义同 EAGAIN,但是错误值可能不同于EAGAIN,所以这两个错误值都需要检查
EBADF(9) 参数 sockfd 不是有效的描述符
ECONNREFUSE 远程主机阻绝网络连接
EFAULT(14) 接收缓冲区指针(参数 buf)指向进程地址空间之外
EINTR(4) 操作被信号中断
EINVAL(22) 参数无效
ENOMEM(12) 无法为 recvmsg 函数分配内存
ENOTCONN 与面向连接关联的套接字尚未被连接上(如 TCP 协议未连接,就通过调用 recv 接收数据)
ENOTSOCK 文件描述符 sockfd 没有引用套接字
ENOENT(2) 没有该文件或目录(接收端未处理完缓冲区数据就关闭套接字,详见下文)

特别:

  • 当函数的返回值为-1,并且 (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) 的情况下,认为当前连接是正常的,可以继续接收数据。
  • 在项目中,还遇到过接收端未处理完缓冲区数据就关闭套接字的情况,此时接收端未发送长度为0的消息到发送端,发送端调用 recv 函数返回-1,errno == ENOENT。这种情况是接收端未处理完数据就去关闭连接,TCP 协议会直接发 RST 报文关闭连接,参考:https://blog.csdn.net/knowledgebao/article/details/84644233

你可能感兴趣的:(Linux,C,linux,网络,c语言)