网络(4):socket中用户自定义缓冲区的原因及方式
来源:互联网 发布:jvm垃圾回收算法 编辑:程序博客网 时间:2024/06/05 05:31
我们在使用TCP/IP编程的时候除了socket有收发数据缓冲区之外,通常我们还要自己定一个数据的收发缓冲区:
1,为什么系统已经有收发缓冲区了,我们还要自定义收发缓冲区呢?
a.假设应用程序需要发送40kB数据,但是操作系统的TCP发送缓冲区只有25kB剩余空间,那么剩下的15kB数据怎么办?如果等待OS缓冲区可用,会阻塞当前线程,因为不知道对方什么时候收到并读取数据。因此网络库应该把这15kB数据缓存起来,放到这个TCP连接的应用层发送缓冲区中,等socket变得可写的时候立刻发送数据,这样“发送”操作不会阻塞。如果应用程序随后又要发送50kB数据,而此时发送缓冲区中尚有未发送的数据(若干kB),那么网络库应该将这50kB数据追加到发送缓冲区的末尾,而不能立刻尝试write(),因为这样有可能打乱数据的顺序。
b. 假如一次读到的数据不够一个完整的数据包,那么这些已经读到的数据是不是应该先暂存在某个地方,等剩余的数据收到之后再一并处理
2.在非阻塞网络编程中,如何设计并使用缓冲区?
一方面希望减少系统调用,一次读的数据越多越划算,那么应该准备一个大的缓冲区。
另一方面,希望减少内存占用。如果有10000个并发连接,每个连接一建立就分配各50kB的读写缓冲区(s)的话,将占用1GB内存,而大多数时候这些缓冲区的使用率很低。可以用readv(2)结合栈上空间解决了这个问题。
3.一下是几种建立缓冲区的方式:
a.方法1: 每次接收到数据的时候开辟一个缓冲区(数据头是数据大小的);然后接受数据填入缓冲区,把缓冲区和IP信息付给任务,压入到任务队列,等任务线程处理; 发送亦然;(小数据可以用栈拷贝的形式)
好处:是接收线程可以一直接收,任务线程一直处理,除了任务锁没有其他交互;
缺点: 每次都重新申请空间,malloc(或new)消耗量大(可以使用内存池优化)
b.方法2: 预先申请一块大的缓冲区(每个连接各申请一个接收缓冲区和发送缓冲区),接收线程有新数据到来的时候从缓冲区中数据结尾获得可用空间插入数据,把连接信息和整个缓冲区压入任务队列,任务线程处理一个任务的数据,就清空缓冲区该段的数据,然后将缓冲区中后面的数据前移(所以每次都是处理的第一个数据区的数据)
好处:减少了malloc
缺点:在数据插入和使用的时候都使用的锁,而且有严重的拷贝复制情况,(如果想任务处理和数据接收不互相锁,必须使用多的一份儿数据拷贝,情况就更糟)
c.方法3:使用线程池,每个线程独立的读数据,当数据满足一个包的时候就当做任务处理;然后将链接信息和用户缓冲区添加到监听队列中;有新的数据来到就激活用一个新的线程处理
好处:仅使用了线程间的锁,(可以使用无锁队列优化),减少数据拷贝
缺点:线程上下文切换开销大, 数据接收分散
D.方法4: 使用绑定线程(一个CPU核一个线程),线程分摊活动连接句(使用管道分发(hash)),单线程接收数据到缓存,然后结合协程做任务处理。
优缺点:还没实现过,不确定
- 网络(4):socket中用户自定义缓冲区的原因及方式
- socket中用户自定义缓冲区的原因及方式
- 网络编程-SOCKET选项-缓冲区
- 驱动程序访问用户模式数据缓冲区的三种方式
- socket缓冲区的影响
- Windows下Socket TCP网络传输及ping-pong缓冲区进程同步研究实现
- 【Linux】管道容量及缓冲区的存储方式
- AngularJS中自定义服务的常见方式及特点
- Java中Socket阻塞的原因
- Socket 字节缓冲区第二种方式
- Socket 字节缓冲区第二种方式
- PL/SQL中记录被另一个用户锁住的原因及处理方法
- 《unix网络编程》(4)缓冲区大小及限制
- java socket报 connection reset的原因和解决方式
- 获得socket的缓冲区大小
- 设置Socket缓冲区的大小
- unix socket 的缓冲区大小
- 为什么在“非阻塞+io复用网络模型”中用户缓冲区管理变得复杂了?
- 启动Mac mysql服务器步骤
- Unity UI(七):交互式控件之Scroll Rect和ScrollView
- 接口与抽象类
- 一天一个设计模式---代理模式
- 51nod 逆序数[NYOJ 逆序数](离散化+树状数组)
- 网络(4):socket中用户自定义缓冲区的原因及方式
- 根据二叉树遍历结果反推树
- gcc链接顺序
- HDU 3579 Hello Kiki【CRT(互质+不互质)统一】
- React Native在直播应用中的实践
- python踩过的坑之py文件命名导致导入包错误
- iOS容易闪退的bug
- Android设计登录界面、找回密码、注册功能
- 【Android 仿微信通讯录 导航分组列表-下】自定义View为RecyclerView打造右侧索引导航栏IndexBar