
linux网络编程系列(十三)--缓冲区设计及收发大量数据
减少系统调用:一次读取尽可能多的数据,这样可以减少频繁的系统调用,提升性能。 减少内存占用:如果有10000个并发连接,每个连接都分配一个50kB的读写缓冲区,内存占用将高达1GB。为了优化内存占用,可以使用readv(2)函数结合栈上空间来处理。
发布日期:2021-05-08 05:59:43
浏览次数:22
分类:精选文章
本文共 1899 字,大约阅读时间需要 6 分钟。
自定义缓冲区与TCP/IP编程
在TCP/IP编程中,除了操作系统提供的socket缓冲区外,通常还需要自定义一个数据的收发缓冲区。这是为了应对网络通信中数据传输的不确定性,确保数据能够高效且可靠地发送和接收。
为什么需要自定义缓冲区
在实际应用中,发送数据时可能会遇到以下情况:
假设需要发送40kB的数据,但操作系统的TCP发送缓冲区仅有25kB的剩余空间。这意味着剩下的15kB数据无法直接通过socket发送。为了避免阻塞当前线程,网络库需要将这15kB数据缓存到TCP连接的应用层发送缓冲区中,等socket变得可写时立即发送。这样可以避免发送操作被阻塞。此外,如果随后又有50kB的数据需要发送,而发送缓冲区中尚有未发送的数据,则需要将新数据追加到缓冲区的末尾,而不是立即尝试写入。这是为了确保数据的传输顺序不会被打乱。对于部分数据未读取的情况,网络库也需要能够暂存已经读到的数据,等待剩余数据到达后再进行处理。缓冲区设计的原则
在设计缓冲区时需要权衡以下几点:
建立缓冲区的方式
在实际实现中,可以采用以下几种方式来建立缓冲区:
1. 每次都重新申请缓冲区
这种方法适用于小数据量的场景。每次接收数据时,动态申请一个缓冲区,将数据填入其中,然后将连接信息和缓冲区内容压入任务队列。任务线程在处理时会清空缓冲区。
优点:接收线程可以独立运行,任务线程负责处理数据,避免了锁的竞争。缺点:每次都动态申请内存(如malloc),内存分配和释放的开销较大。2. 预先申请缓冲区
为每个连接预先分配一个大缓冲区。接收线程在缓冲区尾部插入新数据,任务线程处理时将缓冲区中的数据清空,并将后续数据前移。
优点:减少了动态内存分配的开销。缺点:插入和使用数据时需要加锁,且可能存在大量数据拷贝操作。3. 使用线程池
每个线程独立读取数据,当数据满足一个包的大小时,就作为任务处理。新数据到达时启动一个新线程处理。
优点:减少了锁的竞争,数据拷贝量也较少。缺点:线程上下文切换的开销较大,可能影响数据接收的吞吐量。读写大量内容的实现
为了高效处理大量数据,可以自定义readn和writen函数:
readn函数
ssize_t readn(int fd, char *buf, int size) { char *pbuf = buf; int total = 0; int nread; for (; total < size; ) { nread = read(fd, pbuf, size - total); if (nread == 0) { return total; } if (nread == -1) { if (errno == EINTR) { continue; } return -1; } total += nread; pbuf += nread; } return total;}
writen函数
ssize_t writen(int fd, char *buf, int size) { char *pbuf = buf; int total = 0; int nwrite; for (; total < size; ) { nwrite = write(fd, pbuf, size - total); if (nwrite <= 0) { if (nwrite == -1 && errno == EINTR) { continue; } return -1; } total += nwrite; pbuf += nwrite; } return total;}
这两个函数可以分别用于读取和写入大量数据,确保数据传输的高效性和可靠性。
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月03日 03时23分13秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
基础知识
2019-03-05
nodeName与tagName的区别
2019-03-05
(九)实现页面底部购物车的样式
2019-03-05
在vue中给对象扩展属性的方法
2019-03-05
Neo4j : 通过节点的 id属性 对节点进行查,改,删操作
2019-03-05
Linux标准错误和标准输出重定向到同一个文件
2019-03-05
HTTP Status 404 – Not Found
2019-03-05
【2021年新书推荐】ASP.NET Core 5 and Angular
2019-03-05
python-day3 for语句完整使用
2019-03-05
spring 程序开发步骤
2019-03-05
java基础知识:构造函数
2019-03-05
java基础知识:封装
2019-03-05
linux下安装tomcat服务器
2019-03-05
mysql 中的数据实现递归查询
2019-03-05
linux下远程上传命令scp
2019-03-05
(四)块设备文件
2019-03-05
可重入和不可重入函数
2019-03-05
(2.1)关系模型之关系结构和约束
2019-03-05