关于非阻塞的recv的时候返回的处理
注意recv()如果读到数据为0,那么就表示文件结束了,如果在读的过程中遇到了中断那么会返回-1,同时置errno为EINTR。
因此判断recv的条件:
如果read返回<=0
如果==0
表示文件结束, 处理
如果<0 && errno==EINTR
表示中断,处理
否则,出错
我们举个例子:
int safe_tcp_recv (int sockfd, void *buf, int bufsize)
{
int cur_len;
recv_again:
cur_len = recv (sockfd, buf, bufsize, 0);
//closed by client
if (cur_len == 0)
{
TRACE_LOG ("connection closed by peer, fd=%d", sockfd);
return 0;
}
else if (cur_len == -1)
{
if (errno == EINTR)
goto recv_again;
else
ERROR_LOG ("recv error, fd=%d, errno=%d %m", sockfd, errno);
}
return cur_len;
}
或者
int safe_tcp_recv_n (int sockfd, void *buf, int total)
{
int recv_bytes, cur_len;
for (recv_bytes = 0; recv_bytes < total; recv_bytes += cur_len)
{
cur_len = recv (sockfd, buf + recv_bytes, total - recv_bytes, 0);
//closed by client
if (cur_len == 0) //正常关闭
{
TRACE_LOG ("connection closed by peer, fd=%d", sockfd);
return -1;
}
else if (cur_len == -1)
{
if (errno == EINTR)//还需要在读
cur_len = 0;
else if (errno == EAGAIN)
{
TRACE_LOG ("recv %d bytes from fd=%d", recv_bytes, sockfd);
return recv_bytes;
}
else
{
ERROR_RETURN (("recv tcp packet error, fd=%d, %m", sockfd), -1);
}
}
}
return recv_bytes;
}
但是write()如果写入的数据为0,那么就表示出错,也就是无法写入了,而如果在写的过程中遇到了中断,那么write()会返回-1,同时置errno为EINTR。
因此判断write是否成功时,条件是write返回的结果是否<=0
int safe_tcp_send_n (int sockfd, const void *buf, int total)
{
int send_bytes, cur_len;
for (send_bytes = 0; send_bytes < total; send_bytes += cur_len)
{
cur_len = send (sockfd, buf + send_bytes, total - send_bytes, 0);
//closed by client
if (cur_len == 0)
{
TRACE_LOG ("send tcp packet error, fd=%d, %m", sockfd);
return -1;
}
else if (cur_len == -1)
{
if (errno == EINTR)
cur_len = 0;
else if (errno == EAGAIN)
{
return send_bytes;
}
else
{
TRACE_LOG ("send tcp packet error, fd=%d, %m", sockfd);
return -1;
}
}
}
//TRACE_LOG ("send: fd=%d, len=%d", sockfd, send_bytes);
return send_bytes;
}
首先我们看看recv的返回值:
EAGAIN、EWOULDBLOCK、EINTR与非阻塞 长连接
EWOULDBLOCK用于非阻塞模式,不需要重新读或者写
EINTR指操作被中断唤醒,需要重新读/写
在Linux环境下开发经常会碰到很多错误(设置errno),其中EAGAIN是其中比较常见的一个错误(比如用在非阻塞操作中)。
从字面上来看,是提示再试一次。这个错误经常出现在当应用程序进行一些非阻塞(non-blocking)操作(对文件或socket)的时候。例如,以 O_NONBLOCK的标志打开文件/socket/FIFO,如果你连续做read操作而没有数据可读。此时程序不会阻塞起来等待数据准备就绪返 回,read函数会返回一个错误EAGAIN,提示你的应用程序现在没有数据可读请稍后再试。重新读数据,其实这个也就是说明了一点,网络报还没有发完结束呢,还需要继续读,除非返回的是大于0的值,就代表的是读完了,返回正常读到的网络报的长度。
又例如,当一个系统调用(比如fork)因为没有足够的资源(比如虚拟内存)而执行失败,返回EAGAIN提示其再调用一次(也许下次就能成功)。
Linux - 非阻塞socket编程处理EAGAIN错误
在linux进行非阻塞的socket接收数据时经常出现Resource temporarily unavailable,errno代码为11(EAGAIN),这是什么意思?
这表明你在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏socket的同步,不用管它,下次循环接着recv就可以。 对非阻塞socket而言,EAGAIN不是一种错误。在VxWorks和Windows上,EAGAIN的名字叫做EWOULDBLOCK。
另外,如果出现EINTR即errno为4,错误描述Interrupted system call,操作也应该继续。
最后,如果recv的返回值为0,那表明连接已经断开,我们的接收操作也应该结
关于非阻塞的recv的时候返回的处理相关推荐
- linux命令 recv阻塞时间,linux下close 掉socket 之后 阻塞的recv 不会立即返回
在开发的一个基于rtmp聊天的程序时发现了一个很奇怪的现象. 在windows下当我们执行 closesocket的操作之后,阻塞的 recv会立即返回 -1 . 而在linux下当我们执行close ...
- python复制文件夹不阻塞_11.python并发入门(part14阻塞I/O与非阻塞I/O,以及引入I/O多路复用)...
一.初步了解什么是I/O模型. 1.回顾,用户态与内核态. 操作系统位于应用程序和硬件之间,本质上是一个软件,它由内核以及系统调用组成. 内核:用于运行于内核态,主要作用是管理硬件资源. 系统调用:运 ...
- 一个理解同步异步阻塞非阻塞非常好的解释
作者:知乎用户 链接:https://www.zhihu.com/question/19732473/answer/51734090 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...
- 怎样理解阻塞非阻塞与同步异步的区别
怎样理解阻塞非阻塞与同步异步的区别? 发现很多人对这两个概念往往混为一谈 6 条评论 分享 按投票排序 按时间排序 47 个回答 605赞同 反对,不会显示你的姓名 卢毅 ,Lyft full-sta ...
- 这次,让我们捋清:同步、异步、阻塞、非阻塞
继上一篇说透I/O模型后,我们来谈谈网络 I/O 经常会伴随的几个容易令人混淆的概念:同步.异步.阻塞.非阻塞的区别. 这篇写完之后铺垫就差不多了,之后就正式开始 Netty 深度剖析了,敬请期待,嘻 ...
- 非阻塞recvfrom卡住
背景 多线程模式下,偶尔会遇到recvfrom在非阻塞模式下不能正常返回的情况,使得系统出现假死锁,从而导致整个系统不能提供服务. 剖析 在上图中,如果threadB在进行recvfrom调用时,so ...
- 阻塞/非阻塞 同步/异步
1.同步和异步 关注的是消息的通讯机制 关注对象是被调用者 同步--发出调用时,在没有得到结果之前,该调用不返回.一旦返回就能得到返回值. 调用者主动等待被调用者返回结果 异步--发出调用时,直接 ...
- 网络编程 read 阻塞和非阻塞下的区别
1,read 原型,参数以及返回值. #include <uinstd.h>ssize_t read(int fd, void *buf, size_t nbytes); -----rea ...
- 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值
recv: 阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小, 特别:非阻塞模式下返回 值 <0时并且(errno == EINTR || e ...
最新文章
- 对PostgreSQL的 ctid 的初步认识
- IDEA不能下载插件
- 吴恩达深度学习(一)-第三周:Planar data classification with one hidden layer
- 盘点电机重要应用的七大领域
- 一款在线画图工具的使用(推荐)
- 【无标题】免费论文查重的方法;知网也可以免费查重啦
- excel文件保护忘记密码解除
- BW随手记-项目上零碎总结(SAP销售,开票,获利能力分析)
- react native 自定义Image实现预加载图片及错误之后图片显示
- U-SEM体验模型——让游戏交互设计的维度更加清晰
- bzoj1776[Usaco2010 Hol]cowpol 奶牛政坛
- 售后服务场景智能调度解决方案
- 读书笔记(II) 编译原理及实践
- ​【​观察】云栖大会共话JDM模式 揭秘创新背后的价值和启示
- 后端线上服务监控与报警方案
- 6g运行和8g运行有什么差别
- Linux 如何设置当前时间
- python对于字典d d.get(x、y)_python--字典
- uni-app图片显示
- 2018,微信公众号可能要变天了
热门文章
- TextView实现自动滚动滚动.
- setTimeout里如果有$(this),$(this)指的是谁?
- php 处理 mysql to json, 前台js处理
- 批量删除html网页,批量删除.html · panghuamama/Clearly Local - Gitee.com
- c语言volatile_[技术]为什么单片机C语言编程时某一变量有时乱码
- 餐饮水单打印软件_开发一款餐饮手机app系统软件什么价格?有哪些方面需要考虑?...
- mysql数据库应用的权限层级_MySQL数据库的用户权限管理
- java stack list_JAVA自己实现List接口Stack
- 女士细线毛衣起多少针_从起针到缝合,教你织毛衣的各种要点(详细教程)
- 计算机二级网址打不开,大神为你解决win7系统打不开二级网页链接的操作教程...