目录

答案

深入说明

在 epoll 中的应用

总结

拓展


答案

  1. 阻塞,事情干不完就不要回来了!
  2. 非阻塞,能干多少就是多少,赶紧回来!

深入说明

// 将内核接收缓冲区中的数据 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 设置为非阻塞的。

总结

  1. 在水平触发模式下,recv 和 send 阻塞和非阻塞模式均可。

  2. 在边沿触发模式下,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 阻塞和非阻塞的区别相关推荐

  1. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值

    recv: 阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小, 特别:非阻塞模式下返回 值 <0时并且(errno == EINTR || e ...

  2. recv send 阻塞和非阻塞

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

  3. linux下recv 、send阻塞、非阻塞区别和用法

    非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明:        基本概念: 阻塞IO:: socket 的阻塞模 ...

  4. socket的阻塞模式和非阻塞模式(send和recv函数在阻塞和非阻塞模式下的表现)

    socket的阻塞模式和非阻塞模式 无论是Windows还是Linux,默认创建socket都是阻塞模式的 在Linux中,可以再创建socket是直接将它设置为非阻塞模式 int socket (i ...

  5. TCP send 阻塞与非阻塞

    http://blog.chinaunix.net/uid-8489474-id-2031025.html tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,sen ...

  6. IO模式设置,阻塞与非阻塞的比较,recv参数对性能的影响—O_NONBLOCK(open使用)、IPC_NOWAIT(msgrcv)、MSG_DONTWAIT

    非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明:        基本概念: 阻塞IO:: socket 的阻塞模 ...

  7. 阻塞与非阻塞的IO网络读写

    看我之前的文章就知道,一般对于网络读的socket,都会加上O_NONBLOCK,非阻塞的选项. int setnonblocking(int fd) {int old_option = fcntl( ...

  8. python gevent模块 下载_Python协程阻塞IO非阻塞IO同步IO异步IO

    Python-协程-阻塞IO-非阻塞IO-同步IO-异步IO 一.协程 协程又称为微线程 CPU 是无法识别协程的,只能识别是线程,协程是由开发人员自己控制的.协程可以在单线程下实现并发的效果(实际计 ...

  9. IO之阻塞与非阻塞比较

    在网络程序中遇到的一些问题进行了总结, 这里主要针对的是我们常用的TCP socket相关的总结, 可能会存在错误, 有任何问题欢迎大家提出. 对于网络编程的更多详细说明建议参考下面的书籍 <U ...

最新文章

  1. 远程计算机管理权限,肿么获得远程计算机管理员权限
  2. (总结)Linux的/etc/services文件简析
  3. centos下部署tomcat详解
  4. Transformer温故知新
  5. java将日期作为文件名_获取当前时间作为文件名
  6. unshift() 方法将一个或多个元素添加到数组的开头,并返回新数组的长度
  7. java将mysql数据写入到txt_java 追加写入数据到txt
  8. 公司盘点员工,不上班的员工要给钱吗?
  9. 模型开发:拥抱张量运算
  10. 一个神秘 URL 酿大祸,差点让我背锅!
  11. 2015 2020 r4烧录卡 区别_【2015年和2020年上半年市场资金结构有何差异?】东北证券金融工程择时周报20200802...
  12. 怎么运行java程序_怎么运行java程序?运行java程序的一般步骤?
  13. 74cms 5.0.1版本文件包含漏洞复现
  14. Google ----- 展示搜索的艺术!
  15. 控制面板Plesk, cPanel, DirectAdmin, whmcs,WDCP, AMH比较
  16. 健康系列——如何增强免疫力
  17. Android EditText简单自定义边框样式
  18. 如何解决浏览器的兼容性
  19. 如何从产品层面做需求分析——产品定位
  20. Java API--IO流整理

热门文章

  1. Raspberry Pi 2 Model B Pi4J 示例
  2. AngularJS HTML DOM
  3. Win8 .NET Framework 3.5 离线安装
  4. 推荐 7 个 Github 上近 200k Star 的计算机学习资源,练好前端内功的秘籍!
  5. CDH6.3.2默认管理端口是7180,HDFS相关端口
  6. Java GUI编程:swing实现上传tiff文件至hdfs功能
  7. 【收藏】Win10:路径长度超过260个字符
  8. bind9 安装:部署自建dns系统
  9. JVM调优:常见垃圾回收器组合
  10. docker重启容器命令