函数原型:int recv( SOCKET s, char *buf, int  len, int flags)

功能:不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。

参数一:指定接收端套接字描述符

参数二:指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据

参数三:指明buf的长度

参数四 :一般置为0

阻塞与非阻塞recv返回值没有区分,都是

 >  0  成功接收数据大小

=  0  另外一端关闭了套接字

= -1     错误,需要获取错误码errno(win下是通过WSAGetLastError())

errno被设为以下的某个值:

EAGAIN:套接字已标记为非阻塞,而接收操作被阻塞或者接收超时

对非阻塞socket而言,EAGAIN不是一种错误。在VxWorks和Windows上,EAGAIN的名字叫EWOULDBLOCK。

EBADF:sock不是有效的描述词

ECONNREFUSE:远程主机阻绝网络连接

EFAULT:内存空间访问出错
EINTR:操作被信号中断
EINVAL:参数无效
ENOMEM:内存不足
ENOTCONN:与面向连接关联的套接字尚未被连接上
ENOTSOCK:sock索引的不是套接字

返回值<0时并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况下认为连接是正常的,继续接收。
只是阻塞模式下recv会阻塞着接收数据,非阻塞模式下如果没有数据会返回,不会阻塞着读,因此需要循环读取)。

while(1)
{
    cnt = (int)recv(m_socket, pBuf,RECVSIZE, 0);
    if( cnt >0 )
    {
        //正常处理数据
    }
    else
   {
         if((cnt<0) &&(errno == EAGAIN||errno == EWOULDBLOCK||errno == EINTR))

//这几种错误码,认为连接是正常的,继续接收

{
            continue;//继续接收数据
        }
        break;//跳出接收循环
    }
}

首先阻塞接收的recv有时候会返回0,这仅在对端已经关闭TCP连接时才会发生。

而当拔掉设备网线的时候,recv并不会发生变化,仍然阻塞,如果在这个拔网线阶段,socket被关掉了,后果可能就是recv永久的阻塞了。所以一般对于阻塞的socket都会用setsockopt来设置recv超时,当超时时间到达后,recv会返回错误,也就是-1,而此时的错误码是EAGAIN或者EWOULDBLOCK,POSIX.1-2001上允许两个任意一个出现都行,所以建议在判断错误码上两个都写上。

如果socket是被对方用linger为0的形式关掉,也就是直接发RST的方式关闭的时候,recv也会返回错误,错误码是ENOENT

还有一种经常在代码中常见的错误码,那就是EINTER,意思是系统在接收的时候因为收到其他中断信号而被迫返回,不算socket故障,应该继续接收。但是这种情况非常难再现,我尝试过一边一直在不停的发信号,一边用recv接收数据,也没有出现过。这种异常错误我附近只有一个朋友在用write的时候见到过一次,但是总是会有概率出现的,所以作为完善的程序必须对此错误进行特殊处理。

一般设置超时的阻塞recv常用的方法都如下

Linux环境下,须如下定义:struct timeval timeout = {3,0}; 
//设置发送超时
setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));

//设置接收超时
setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval));
--------------------- 
作者:AncientCastle 
来源:CSDN 
原文:https://blog.csdn.net/hq354974212/article/details/76077635 
版权声明:本文为博主原创文章,转载请附上博文链接!

recv函数返回值总结相关推荐

  1. recv函数返回值说明

    recv函数 int recv( SOCKET s, char FAR *buf, int len, int flags); 不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据. ...

  2. mysql linux 函数返回值_linux recv函数返回值分析

    函数原型: ssize_t recv(int sockfd, void *buf, size_t len, int flags); 该函数第一个参数制定接收端套接字描述符; 第二个参数指明一个缓冲区, ...

  3. c语言recv函数返回值,谈谈recv()函数的返回值

    网上某论坛有这样一个问题:当recv()函数的返回值为0时,能不能在接收端不关闭套接字,以便这条建立好的C/S通信下次可以直接使用? 我对这个问题的回答是:不能. 原因是:此时即使接收端不关闭套接字, ...

  4. recv函数和send函数返回值错误处理

    本文中分析的都是非阻塞态的socket错误代码,因为阻塞态也不会出现EWOULDBLOCK错误. 1.recv函数: 返回值<0时并且(errno == EINTR || errno == EW ...

  5. select()函数返回值及select与socket阻塞的关系及select函数的意义

    1.select()函数返回值 select的返回值与recv函数的返回值十分类似,都分>0,=0,<0三种情况. >0:有事件发生, FD_ISSET(socket, &f ...

  6. Linux网络编程:recv的返回值

    recv是网络编程中用于TCP传输接收数据的接口,由于工作中一直没有接触到网络编程,虽然知道这个函数,但是没有使用经验,所有对接口细节不是很了解. 直到前阵子在项目中调试第三方的源码时,跟踪到这个函数 ...

  7. C++ 笔记(15)— 引用(声明引用、引用作为参数、引用作为函数返回值、const 用于引用)

    引用是变量的别名.也就是说,它是某个已存在变量的另一个名字.一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量. 1. 创建引用 要声明引用,可使用引用运算符 & ,如下面的 ...

  8. C++ 笔记(02)— 程序结构(头文件说明、命名空间、函数返回值、函数参数、注释、语句结束符、cin/cout)

    先看以下代码 #include <iostream> #include <string> using namespace std;int main() // main() 是程 ...

  9. C指针7:指针作为函数返回值

    C语言允许函数的返回值是一个指针(地址),我们将这样的函数称为指针函数.下面的例子定义了一个函数 strlong(),用来返回两个字符串中较长的一个: #include <stdio.h> ...

  10. 使用指针做函数返回值

    使用指针做函数返回值 1.当使用指针做为函数的返回值时,主函数处的char *p;将获得调用函数char *pf;的值,即一个地址值,如oxAE72.此时需要我们注意的是该地址值所指向的空间是否存在( ...

最新文章

  1. 北大华为鹏城联合首次提出视觉 Transformer 后量化算法!
  2. visual studio code安装shadertoy特效环境
  3. 初窥江湖之PhotoShop抠图(一)
  4. 64位进程调用32位dll的解决方法
  5. sdut 活动选择问题
  6. 解决SQLServer占用80端口问题
  7. c语言和python的堆栈,python - 在C ++中更快地执行两个程序的可能解释(与Python比较)? - 堆栈内存溢出...
  8. Go github.com/e421083458/golang_common/lib
  9. 易语言计算机代码,易语言基础教程之简单代码的编写
  10. AB实验的高端玩法系列4- 实验渗透低?用户未被触达?CACE/LATE
  11. unicode编码和utf-8编码详解
  12. iOS包体积优化实践
  13. Debezium报错处理系列九:“ddl“ : “# Dummy event replacing event type 160 that slave cannot handle.“
  14. 世界上最有名和哲理的17句话
  15. spark 无法读取hive 3.x的表数据
  16. storyboard 苹果启动图_使用Xcode storyboard 来提供 app 的启动屏幕
  17. 前端工作过程遇到的问题总结(九)
  18. 架构设计:架构设计要平衡兼顾多方需求
  19. 铁损分离-磁滞回线面积-离散点的面积
  20. android https请求证书过滤白名单,Android处理https请求的证书问题

热门文章

  1. [转帖]超能课堂:Intel平台芯片组变迁史
  2. Adobe Flash Player历史版本下载
  3. Python网络爬虫实战-李强强-专题视频课程
  4. Android OpenGL ES 开发教程(12):绘制一个20面体
  5. FireFox把Gmail变成大容量网络硬盘
  6. [转]Netlog 的数据库及 LAMP 架构
  7. 【图算法】(3) 网络的基本静态几何特征(二),附networkx完整代码
  8. snipaste如何滚动截图_3款工具满足你对截图软件的所有想象
  9. spss回归分析笔记记录
  10. SlideLive:提供阶梯类型PPT模板下载