打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用socket.recv时出现阻塞,怎么处理
recv是socket编程中最常用的函数之一,在阻塞状态的recv有时候会返回不同的值,而对于错误值也有相应的错误码,分别对应不同的状态,下面是我针对常见的几种网络状态的简单总结。
      首先阻塞接收的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常用的方法都如下:
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));
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
TCP/IP编程基础——超时、多路复用、非阻塞
socket 请求接收完整的一个http响应
linux中select()函数分析
socket异步通信
PYTHON:=[WinError 10035]无法执行非阻塞套接字操作。\n
winsock 如何判断socket是否有效
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服