在《socket 数据的接受和发送》一节中讲到,可以使用 write()/send() 函数发送数据,使用 read()/recv() 函数接收数据,本节就来看看数据是如何传递的。

socket 缓冲区

每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区。
write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情。
TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决于当时的网络情况、当前线程是否空闲等诸多因素,不由程序员控制。
read()/recv() 函数也是如此,也从输入缓冲区中读取数据,而不是直接从网络中读取。

图:TCP套接字的I/O缓冲区示意图
这些I/O缓冲区特性可整理如下:

  • I/O缓冲区在每个TCP套接字中单独存在;
  • I/O缓冲区在创建套接字时自动生成;
  • 即使关闭套接字也会继续传送输出缓冲区中遗留的数据;
  • 关闭套接字将丢失输入缓冲区中的数据。

输入输出缓冲区的默认大小一般都是 8K,可以通过 getsockopt() 函数获取:

unsigned optVal;
int optLen = sizeof(int);
getsockopt(servSock, SOL_SOCKET, SO_SNDBUF, (char*)&optVal, &optLen);
printf("Buffer length: %dn", optVal);

运行结果:
Buffer length: 8192

阻塞模式

对于TCP套接字(默认情况下),当使用 write()/send() 发送数据时:
1) 首先会检查缓冲区,如果缓冲区的可用空间长度小于要发送的数据,那么 write()/send() 会被阻塞(暂停执行),直到缓冲区中的数据被发送到目标机器,腾出足够的空间,才唤醒 write()/send() 函数继续写入数据。
2) 如果TCP协议正在向网络发送数据,那么输出缓冲区会被锁定,不允许写入,write()/send() 也会被阻塞,直到数据发送完毕缓冲区解锁,write()/send() 才会被唤醒。
3) 如果要写入的数据大于缓冲区的最大长度,那么将分批写入。
4) 直到所有数据被写入缓冲区 write()/send() 才能返回。
当使用 read()/recv() 读取数据时:
1) 首先会检查缓冲区,如果缓冲区中有数据,那么就读取,否则函数会被阻塞,直到网络上有数据到来。
2) 如果要读取的数据长度小于缓冲区中的数据长度,那么就不能一次性将缓冲区中的所有数据读出,剩余数据将不断积压,直到有 read()/recv() 函数再次读取。
3) 直到读取到数据后 read()/recv() 函数才会返回,否则就一直被阻塞。
这就是TCP套接字的阻塞模式。所谓阻塞,就是上一步动作没有完成,下一步动作将暂停,直到上一步动作完成后才能继续,以保持同步性。

TCP套接字默认情况下是阻塞模式,也是最常用的。当然也可以更改为非阻塞模式

recv函数阻塞_socket缓冲区以及阻塞模式详解相关推荐

  1. java网络编程阻塞_Java网络编程由浅入深三 一文了解非阻塞通信的图文代码示例详解...

    本文详细介绍组成非阻塞通信的几大类:Buffer.Channel.Selector.SelectionKey 非阻塞通信的流程ServerSocketChannel通过open方法获取ServerSo ...

  2. 创建三个并发进程linux,Linux下几种并发服务器的实现模式(详解)

    1>单线程或者单进程 相当于短链接,当accept之后,就开始数据的接收和数据的发送,不接受新的连接,即一个server,一个client 不存在并发. 2>循环服务器和并发服务器 1.循 ...

  3. 1 linux下tcp并发服务器的几种设计的模式套路,Linux下几种并发服务器的实现模式(详解)...

    1>单线程或者单进程 相当于短链接,当accept之后,就开始数据的接收和数据的发送,不接受新的连接,即一个server,一个client 不存在并发. 2>循环服务器和并发服务器 1.循 ...

  4. HS6621 串口透传 模式 - [详解]

    文章目录 HS6621串口透传模式详解 遇到的问题现象 UART发送源码 HS6621CG 内核的中断优先级 本人项目中的透传代码 UART0_Recv_IRQ UART1_Recv_IRQ 按照以上 ...

  5. Spotify敏捷模式详解三部曲第一篇:研发团队

    本文转自:Scrum中文网 引言 2018年4月,来自北欧瑞典的音乐流媒体公司.百亿美元独角兽Spotify创造了历史,它成为了当代上市公司当中,第一家通过"直接上市"的方式在美国 ...

  6. linux apache两种工作模式详解

    apache两种工作模式详解 刚接触这两个配置时很迷糊,全部开启或全部注释没有几多变化.今天搜索到这么一篇讲得还不错的文章,看了几篇,还是不能完全记住,做一个收藏. 空闲子进程:是指没有正在处理请求的 ...

  7. 敏捷开发系列学习总结(13)——Spotify敏捷模式详解三部曲第一篇:研发团队

    分享一个大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!点击浏览教程 引言 2018年4月,来自北欧瑞典的音乐流媒体公司.百亿美元独角兽Spotify创造 ...

  8. IoC与DI工厂、单例、原型模式详解

    1.工厂模式 1.1 工厂模式的由来 在现实生活中我们都知道 原始社会自给自足(没有工厂) 农耕社会有了小作坊(简单工厂,如民间酒坊) 工业革命后有了流水线(工厂方法,自产自销) 现代产业链中有代工厂 ...

  9. jQuery: 插件开发模式详解 $.extend(), $.fn, $.widget()

    原文:http://www.codeceo.com/article/jquery-plugin-develop.html 软件开发过程中是需要一定的设计模式来指导开发的,有了模式,我们就能更好地组织我 ...

  10. python中search和match的区别_Python中正则表达式match()、search()函数及match()和search()的区别详解...

    match()和search()都是python中的正则匹配函数,那这两个函数有何区别呢? match()函数只检测RE是不是在string的开始位置匹配, search()会扫描整个string查找 ...

最新文章

  1. Oracle 赋权和回收权限的生效时间
  2. 大连理工大学 计算机复试分数线,2020大连理工大学考研复试分数线已公布
  3. Linux提权CVE-2022-0847分析
  4. OpenStack vlan教程 (操作篇)
  5. android 集成同一interface不同泛型_Dig101:Go之读懂interface的底层设计
  6. 判断只有符号数字 java_java编程 判断输入的字符,数字,及其他符号的个数
  7. 机器学习实战 | SKLearn最全应用指南
  8. 我是如何拿到百度计算机视觉暑期实习offer的?百度面经(成功上岸!已拿offer)
  9. 深度学习(六十五)移动端网络MobileNets
  10. 如何在没有安全启动或 TPM 2.0 的传统 BIOS 上安装 Windows 11
  11. URL 和 URI 区别
  12. 东北大学计算机硬件题库,东北大学计算机硬件试题.pdf
  13. Android的启动模式:singleTask与singleTop的使用
  14. 抖音自拍特效如何java实现_抖音特效在 Web 端的实现
  15. c# emgucv 切图_自己积累的一些Emgu CV代码(主要有图片格式转换,图片裁剪,图片翻转,图片旋转和图片平移等功能)...
  16. 手把手教你最近很火的 微信公众号测试号推送消息
  17. 14.嵌入式控制器EC实战 SMBus读取电池信息并控制充放电
  18. 软件研发落地实践,要从设计就开始
  19. 美团已开始研发大模型 ;华为MetaERP全球上线;金山软件一季度净利润同比增长96%丨每日大事件...
  20. 我用过的最好脑图工具——Xmind(含安装包)

热门文章

  1. 论文笔记_S2D.06-2018-BMVC-用于实时语义分割的轻量级精细网络RefineNet
  2. 机器学习课程笔记【十四】- 增强学习和自适应控制控制论
  3. 深度学习笔记(二)——VGG
  4. Spring框架 @ResponseBody注解 编码问题: 论设置 Accept 的重要性
  5. java虚拟机学习笔记(五)---运行时的数据区域
  6. 基于windows fiber的协程(coroutine)实现
  7. EF的注解Annotation和Fluent API
  8. JQuery插件iScroll实现下拉刷新,滚动翻页特效
  9. 程序状态字寄存器PSW
  10. 【观点讨论与支撑】真的是而立之年没有立,以后就没有希望了吗?