socket缓冲区

每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区。

write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情。

TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决于当时的网络情况、当前线程是否空闲等诸多因素,不由程序员控制。

read()/recv() 函数也是如此,也从输入缓冲区中读取数据,而不是直接从网络中读取。


图:TCP套接字的I/O缓冲区示意图

这些I/O缓冲区特性可整理如下:

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

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

  1. unsigned optVal;
  2. int optLen = sizeof(int);
  3. getsockopt(servSock, SOL_SOCKET, SO_SNDBUF, (char*)&optVal, &optLen);
  4. printf("Buffer length: %d\n", 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套接字的阻塞模式。所谓阻塞,就是上一步动作没有完成,下一步动作将暂停,直到上一步动作完成后才能继续,以保持同步性。

socket缓冲区以及阻塞模式相关推荐

  1. socket缓冲区以及阻塞模式详解

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

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

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

  3. socket的阻塞模式和非阻塞模式

    文章目录 socket的阻塞模式和非阻塞模式 如何将socket设置为非阻塞模式 send和recv函数在阻塞和非阻塞模式下的表现 非阻塞模式下send和recv函数的返回值总结 阻塞与非阻塞sock ...

  4. socket阻塞和非阻塞模式

    socket阻塞和非阻塞模式 本文讨论Linux下的socket套接字 一.同步.异步阻塞和非阻塞 同步:主动请求并等待IO操作完成的方式 异步:主动请求数据后,可以去处理其它任务,随后等待IO操作完 ...

  5. java socket 阻塞模式_(四) 如何将socket设置为非阻塞模式

    1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket(    _In_ int af,   ...

  6. Linux下Socket通信中非阻塞connect、select、recv 和 recvfrom、send和sendto大致讲解,附带非租塞connect代码、MSG_NOSIGNAL

    linux中send函数MSG_NOSIGNAL异常消息 在服务器端用ctrl+c 来结束服务器接收进程来模拟服务器宕机的情况,结束服务 socket 进程之后,服务端自然关闭进程,可是 client ...

  7. UE4 Socket多线程非阻塞通信【2】

    昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心 紧接着第一部分,别说话,勿打断我游离的思绪我们走我们走... 二.消息结构&收发队列 先不急着往下走,先捋一捋,不知道自己要干什么地走下去是一件 ...

  8. UE4 Socket多线程非阻塞通信【1】

    昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心 前面写了一篇有关于虚幻4加载第三方库的博客思前顾后,感觉细节还是有必要拎起来注意下. ue4自带的Fsocket用起来依旧不是那么的顺手,感觉超出了我的 ...

  9. UDP socket 设置为的非阻塞模式

    UDP socket 设置为的非阻塞模式  Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct s ...

最新文章

  1. 机器人建图、感知和交互的语义研究综述
  2. java pkcs1转pkcs8_.NET Core RSA密钥的xml、pkcs1、pkcs8格式转换和JavaScript、Java等语言进行对接...
  3. ElementUI中el-radio-group使用v-model绑定是属性为String字符串类型时不回显数据
  4. SpringBoot https访问控制
  5. 人行二代征信报告模版_人行首度明确,替代数据纳入征信管理!美化信用报告,难了...
  6. 多进程减少多个文件的内存占用
  7. python快速编程入门课本第六章_python编程快速上手第六章实践项目参考code
  8. 系统架构师学习笔记-系统开发基础知识(一)
  9. 某大型银行深化系统之十七:性能设计之二
  10. 吹嘘自己,只是想别人从吾这里学点东西
  11. psd导出切片html 分隔符,PHOTO SHOP里如何能把PSD的自动切成切片?存为HTML格式?
  12. dhcp authoritative参数作用
  13. 利用INFOPATH2007VS2005开发MOSS工作流详解 --收藏
  14. 波士顿地区Airbnb价格预测Project (一)
  15. ArcGIS Desktop、Arcengine、ArcObjects_SDK for NET.Framework安装教程
  16. wordpress网站侧边栏添加广告位代码
  17. 拉格朗日乘数求极值方法
  18. Device Orientation——设备方向
  19. javaScript中三大家族总结
  20. hdu 4561 模拟小题or连续最大积

热门文章

  1. Uva 11600 期望DP
  2. 软件架构师的工作流程
  3. 航旅事业群面试(li)
  4. Spring+Hibernate配置多数据源
  5. python -- 字符串的方法及注释
  6. Hadoop学习总结:Map-Reduce的过程解析
  7. MS-SQL中的事务
  8. python字符串的冒泡排序_如何实现python冒泡排序算法?
  9. 【数据结构与算法】之深入解析“二叉树的锯齿形层序遍历”的求解思路与算法示例
  10. 《每日一题》62. Unique Paths 不同路径