recv是socket编程中最常用的函数之一,在阻塞状态的recv有时候会返回不同的值,而对于错误值也有相应的错误码,分别对应不同的状态,下面是我针对常见的几种网络状态的简单总结。
首先阻塞接收的recv有时候会返回0,这仅在socket被正常关闭时才会发生。
而当拔掉设备网线的时候,recv并不会发生变化,仍然阻塞,如果在这个拔网线阶段,socket被关掉了,后果可能就是recv永久的阻塞了。
所以一般对于阻塞的socket都会用setsockopt来设置socket的超时。
当超时时间到达后,recv会返回错误,也就是-1,而此时的错误码是EAGAIN或者EWOULDBLOCK,POSIX.1-2001上允许两个任意一个出现都行,所以建议在判断错误码上两个都写上。
如果socket是被对方用linger为0的形式关掉,也就是直接发RST的方式关闭的时候,recv也会返回错误,错误码是ENOENT
还有一种经常在代码中常见的错误码,那就是EINTER,意思是系统在接收的时候因为收到其他中断信号而被迫返回,不算socket故障,应该继续接收。但是这种情况非常难再现,我尝试过一边一直在不停的发信号,一边用recv接收数据,也没有出现过。这种异常错误我附近只有一个朋友在用write的时候见到过一次,但是总是会有概率出现的,所以作为完善的程序必须对此错误进行特殊处理。
一般设置超时的阻塞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 出错 =0 连接关闭 >0 接收到数据大小。
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));

相关推荐
CMOS 模拟开关MAX4729_MAX4730
IGBT的电流是如何定义的
寻求PCB设计合作!
光导纤维控制双向晶闸管交流开关电路
碳化硅何以英飞凌?—— SiC MOSFET性能评价的真相
面向科学仿真的开放模型系列NVIDIA Apollo正式发布
触摸通断电子开关电路
阿里芯片子公司平头哥拟分拆并筹备IPO,AI芯片性能据称可比肩英伟达H20
CS00301 高精度智能型锂电池充电芯片
寻求PCB设计合作!
串联光电耦合器控制晶闸管开关电路
▲纯HTML型空间 适合个人用户、小型企业快速低成本地创建网上家园!
寻求PCB设计合作!
高速数据传输下连接器等的测试和分析
CS51411 CS51412 CS51413 CS51414 低电压降压转换器
英伟达在人工智能天气预报领域开辟新路
连接器系统的安全性
TI的可扩展型 TDA 高性能SoC产品系列
BL8505 高效低噪声PFM DC_DC 升压稳压器
bq24001 bq24002 bq24003 锂离子电池充电器
栅极氧化层在SiC MOSFET设计中的重要作用
人工智能正在解决你的系统故障
重新审视芯片市场:2030规模预估上调至1.6万亿美元
欧度最新军用通讯连接器产品介绍
半导体模拟开关电路
寻求PCB设计合作!
用于插针和插孔连接器的全新高性能合金
本田与通用汽车解散其燃料电池系统合作关系
采用光敏电阻的光控开关
3M 互连革命—新一代无卤素、高挠、高速线缆