recv 和 send 阻塞和非阻塞的区别
目录
答案
深入说明
在 epoll 中的应用
总结
拓展
答案
- 阻塞,事情干不完就不要回来了!
- 非阻塞,能干多少就是多少,赶紧回来!
深入说明
// 将内核接收缓冲区中的数据 copy 到应用层中用户的 buffer 中。
int recv(int sockfd, void *buf, size_t len, int flag); // 将应用层中用户的 buffer 中的数据 copy 到内核发送缓冲区中。
int send(int sockfd, void *buf, size_t len, int flag);
1、recv
阻塞模式下,如果内核的接收缓冲区中没有数据时,该函数就会阻塞。
非阻塞模式下,如果内核的接收缓冲区中没有数据时,该函数就会返回。
2、send
阻塞模式下,如果发送缓冲区剩余的空间小于要发送的数据的大小,那么该函数会阻塞。
非阻塞模式下,如果发送缓冲区剩余的空间大于要发送的数据的大小,那么该函数会返回。
在 epoll 中的应用
1、水平触发模式(LT)
在该模式下,recv 和 send 为阻塞和非阻塞,结果是一样的。
举 recv 栗子来说,因为在该触发模式下,只要内核的接收缓冲区中有数据,epoll_wait() 函数都会返回,这就导致了虽然 recv 是阻塞模式的,但是每次调用时,内核缓冲区都是有数据的,所以不会导致 recv 阻塞。当然了,当 recv 时是非阻塞的,就更不会造成阻塞情况了。同理,对于 send 也是一样的。
2、边沿触发模式(LT)
在该模式下,recv 和 send 需要为非阻塞模式,不然就会有问题。
还是举 recv 栗子来说,因为在该模式下,内核的接收缓冲区来数据了,那么 epoll_wait() 函数就会返回,但是仅仅返回一次,它可不管你是否在该次中是否完全取走了内核接收缓冲区中的数据。
在上述的前提下,recv 需要一个 while (true) 循环,保证将缓冲区中的数据取空。这就产生了一个问题,因为假如 recv 是阻塞的,那么当内核缓冲区中没有数据时,该函数就会阻塞,这是致命的,所以 recv 必须是非阻塞的。
同理,对于 send 也是一样的。理想情况时,终于有机会向对端发送数据了,一定要将想发的数据发尽。这就有问题了,如果是阻塞的,如果发到一半,发送缓冲区满了,那么该函数就阻塞了,实际上要避免这种情况,所以要将该 send 设置为非阻塞的。
总结
在水平触发模式下,recv 和 send 阻塞和非阻塞模式均可。
在边沿触发模式下,recv 和 send 必须为非阻塞模式。
拓展
1、将socket设置为非阻塞模式的方法。(socket设置为非阻塞的,recv 和 send 要设置为非阻塞的)
int flags = fcntl(sockfd, F_GETFL, 0); //获取文件的flags值。fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); //设置成非阻塞模式;
int n = recv(fd, pbuff, kBuffLen, MSG_DONTWAIT);
2、将socket设置为阻塞模式的方法。
int flags = fcntl(sockfd, F_GETFL, 0); //获取文件的flags值。fcntl(sockfd, F_SETFL, flags | ~O_NONBLOCK); //设置成阻塞模式;
int n = recv(fd, pbuff, kBuffLen, 0); // flag = 0,默认是阻塞的。
(SAW:Game Over!)
recv 和 send 阻塞和非阻塞的区别相关推荐
- 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值
recv: 阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小, 特别:非阻塞模式下返回 值 <0时并且(errno == EINTR || e ...
- recv send 阻塞和非阻塞
int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据 ...
- linux下recv 、send阻塞、非阻塞区别和用法
非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明: 基本概念: 阻塞IO:: socket 的阻塞模 ...
- socket的阻塞模式和非阻塞模式(send和recv函数在阻塞和非阻塞模式下的表现)
socket的阻塞模式和非阻塞模式 无论是Windows还是Linux,默认创建socket都是阻塞模式的 在Linux中,可以再创建socket是直接将它设置为非阻塞模式 int socket (i ...
- TCP send 阻塞与非阻塞
http://blog.chinaunix.net/uid-8489474-id-2031025.html tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,sen ...
- IO模式设置,阻塞与非阻塞的比较,recv参数对性能的影响—O_NONBLOCK(open使用)、IPC_NOWAIT(msgrcv)、MSG_DONTWAIT
非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明: 基本概念: 阻塞IO:: socket 的阻塞模 ...
- 阻塞与非阻塞的IO网络读写
看我之前的文章就知道,一般对于网络读的socket,都会加上O_NONBLOCK,非阻塞的选项. int setnonblocking(int fd) {int old_option = fcntl( ...
- python gevent模块 下载_Python协程阻塞IO非阻塞IO同步IO异步IO
Python-协程-阻塞IO-非阻塞IO-同步IO-异步IO 一.协程 协程又称为微线程 CPU 是无法识别协程的,只能识别是线程,协程是由开发人员自己控制的.协程可以在单线程下实现并发的效果(实际计 ...
- IO之阻塞与非阻塞比较
在网络程序中遇到的一些问题进行了总结, 这里主要针对的是我们常用的TCP socket相关的总结, 可能会存在错误, 有任何问题欢迎大家提出. 对于网络编程的更多详细说明建议参考下面的书籍 <U ...
最新文章
- 远程计算机管理权限,肿么获得远程计算机管理员权限
- (总结)Linux的/etc/services文件简析
- centos下部署tomcat详解
- Transformer温故知新
- java将日期作为文件名_获取当前时间作为文件名
- unshift() 方法将一个或多个元素添加到数组的开头,并返回新数组的长度
- java将mysql数据写入到txt_java 追加写入数据到txt
- 公司盘点员工,不上班的员工要给钱吗?
- 模型开发:拥抱张量运算
- 一个神秘 URL 酿大祸,差点让我背锅!
- 2015 2020 r4烧录卡 区别_【2015年和2020年上半年市场资金结构有何差异?】东北证券金融工程择时周报20200802...
- 怎么运行java程序_怎么运行java程序?运行java程序的一般步骤?
- 74cms 5.0.1版本文件包含漏洞复现
- Google ----- 展示搜索的艺术!
- 控制面板Plesk, cPanel, DirectAdmin, whmcs,WDCP, AMH比较
- 健康系列——如何增强免疫力
- Android EditText简单自定义边框样式
- 如何解决浏览器的兼容性
- 如何从产品层面做需求分析——产品定位
- Java API--IO流整理