缓冲区设置

缓冲区设计

一、简介

在网络通讯中,用户态缓冲区和内核态缓冲区的大小设定对于优化网络性能和确保数据传输可靠性至关重要。下图是网路通讯的内核缓冲区使用情况:
在这里插入图片描述
数据的读写都需要进行系统调用,从用户态切换到内核态去接收数据,结束后需要切换回用户态;
在这里插入图片描述

二、网络数据的传输过程:
  • 发送
    1. 应用程序通过系统调用将用户数据拷贝sk_buff,并放到socket的发送缓冲区中
    2. 网络协议栈从socket法案送缓冲区中取出sk_buffer,并克隆一个新的sk_buffer(用于丢失重传)
    3. 向下依次增加TCP/UDP头部、IP头部、帧头(MAC头)、帧尾,(tcp层进行数据分段、IP层进行数据分片)
    4. 触发软件中断,通知网卡驱动程序有新的网络数据需要发送
    5. 网卡驱动程序从发送队列中取出sk_buffer写到ringbuffer(内存DMA区域)
    6. 网卡发送数据,发送成功后触发硬件中断,释放sk_buffer和ringbuffer没存
    7. 当接收到tcp报文的ack应答后释放sk_buffer
  • 接收
    1. 网卡接收到数据包,通过DMA协处理器将数据写入内存ringbuffer结构中
    2. 网卡向cpu发起硬件中断,cpu收到中断请求,根据中断表查找中断处理函数,进行中断处理
    3. 中断处理函数将屏蔽中断,发起软件中断
    4. 内核ksoftirqd软件中断线程负责软件中断处理,该线程从ringbuffer中逐个取出数据帧到sk_buffer
    5. 从帧头取出ip协议,去掉帧头帧尾
    6. 根据协议五元组找到socket,并将数据取出放到sicket的接收缓冲区中,软件中断处理结束后开启硬件中断
    7. 应用程序通过系统调用将socket中的接收缓冲区的数据拷贝到用户层缓冲区
用户态缓冲区(User-Space Buffer)

用户态缓冲区是指在应用程序地址空间中分配的缓冲区,用于存储待发送或已接收的数据。调整用户态缓冲区的大小可以影响应用程序处理数据的能力,特别是在高吞吐量或低延迟要求的场景中。

  • 在C/C++中,可以通过setsockopt函数来调整TCP或UDP套接字的发送(SO_SNDBUF)和接收(SO_RCVBUF)缓冲区大小。例如:

    1int snd_buff_size = 8192; // 自定义的发送缓冲区大小
    2int rcv_buff_size = 16384; // 自定义的接收缓冲区大小
    3setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &snd_buff_size, sizeof(snd_buff_size));
    4setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcv_buff_size, sizeof(rcv_buff_size));
    
  • 注意,实际设置的缓冲区大小可能会受到操作系统限制,并且可能不是精确设置的值。有时,内核可能会调整至最接近的允许值,通常是用户请求值的两倍。

三、内核态缓冲区(Kernel-Space Buffer)

内核态缓冲区是操作系统内核管理的一部分,用于在网络接口和用户空间之间暂存数据。它的大小直接影响到网络数据包的处理效率,尤其是在网络拥塞或高流量情况下。

  • 对于Linux系统,可以通过修改内核参数来调整某些类型的内核缓冲区大小,例如通过编辑/etc/sysctl.conf文件或使用sysctl命令动态调整。例如,调整网络接收缓冲区的默认最小值和最大值:

    # 动态调整
    sudo sysctl -w net.core.rmem_default=xxxx # 设定默认接收缓冲区大小
    sudo sysctl -w net.core.rmem_max=yyyy    # 设定最大接收缓冲区大小# 或者永久修改,在/etc/sysctl.conf中添加:
    net.core.rmem_default=xxxx
    net.core.rmem_max=yyyy
    
  • 对于特定设备,如串口,可以通过Linux命令行工具(如stty)或者编程方式来调整其缓冲区大小。

设置原则

  • 缓冲区大小的选择应基于实际应用场景,包括网络带宽、期望的延迟、以及可能遇到的网络拥塞情况。
  • 通常,较大的缓冲区可以减少数据包丢失,但在高流量下可能导致更高的延迟,因为数据在缓冲区中排队等待处理的时间更长。
  • 较小的缓冲区可以降低延迟,但在网络拥塞时更容易导致数据包丢失。
  • 最佳实践是通过测试和监控来确定最适合的缓冲区大小,有时这可能需要多次调整和验证。
四、缓冲区的设计
  • read/write阻塞io,通过阻塞线程的方式等待io就绪
  • reactor网络模型,io多路复用检测多路连接io是否就绪,在事件循环中依次处理操作io
  • proactor网络模型,异步io,内核完成检测io以及操作io,等待完成后向用户层抛出完成通知

以上这几种网络都对用户态的缓冲区设计没有影响

1、设计方案:
  • 定长的buffer

    • 优点:结构简单
    • 缺点:频繁挪动数据;没有扩容和缩容机制
  • 环形缓冲区ringbuffer

    • 优点:环形结构,不需要挪动数据
    • 缺点:空间不连续;没有扩容和缩容机制
      结构设计入下
      在这里插入图片描述
  • chainbuffer

    • 优点:不需要挪动数据,可以实现动态扩容和缩容

      结构设计图如下: 在这里插入图片描述

2、环形缓冲区

下面主要介绍一下ringbufeer,其数据结构为

struct ringbuffer_s {uint32_t size;	// 环形结构的大小uint32_t tail;	// 尾指针uint32_t head;	// 头指针uint8_t * buf;	// 数据指针
};

创建环形缓冲区

// 用于将num值扩展大最近比num值大的2^n的值,用于后面计算优化(将取余操作优化为位运算操作)
static inline uint32_t roundup_power_of_two(uint32_t num) {if (num == 0) return 2;int i = 0;for (; num != 0; i++)num >>= 1;return 1U << i;
}
buffer_t * buffer_new(uint32_t sz) {if (!is_power_of_two(sz)) sz = roundup_power_of_two(sz);// 创建buffer时大小要加上结构体本身的大小buffer_t * buf = (buffer_t *)malloc(sizeof(buffer_t) + sz);if (!buf) {return NULL;}buf->size = sz;buf->head = buf->tail = 0;buf->buf = (uint8_t *)(buf + 1);return buf;
}

添加数据

int buffer_add(buffer_t *r, const void *data, uint32_t sz) {if (sz > rb_remain(r)) {return -1;}uint32_t i;// 当前位置到尾部的空间大小是否满足插入数据的大小i = min(sz, r->size - (r->tail & (r->size - 1)));// 插入到数据尾部memcpy(r->buf + (r->tail & (r->size - 1)), data, i);// 剩余的数据插到头部memcpy(r->buf, data+i, sz-i);r->tail += sz;return 0;
}

数据获取移除

// 数据移除只需要移动指针的位置即可
int buffer_remove(buffer_t *r, void *data, uint32_t sz) {assert(!rb_isempty(r));uint32_t i;sz = min(sz, r->tail - r->head);i = min(sz, r->size - (r->head & (r->size - 1)));// 将数据拷贝到data中memcpy(data, r->buf+(r->head & (r->size - 1)), i);memcpy(data+i, r->buf, sz-i);// 更新数据头指针位置,移除数据r->head += sz;return sz;
}

数据空间位置调整

// 将数据挪动到头部位置,使得数据保持连续
uint8_t * buffer_write_atmost(buffer_t *r) {// 使用位操作代替取余操作,size必须要是2^nuint32_t rpos = r->head & (r->size - 1);uint32_t wpos = r->tail & (r->size - 1);if (wpos < rpos) {// 数据不连续,挪动数据,使其保持连续uint8_t* temp = (uint8_t *)malloc(r->size * sizeof(uint8_t));memcpy(temp, r->buf+rpos, r->size - rpos);memcpy(temp+r->size-rpos, r->buf, wpos);free(r->buf);r->buf = temp;return r->buf;}// 返回数据起始位置return r->buf + rpos;
}

专属学习链接:https://xxetb.xetslk.com/s/36yiy3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/29648.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

昂科烧录器支持TI德州仪器的超低功耗微控制器MSP430F2013IRSAR

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中TI德州仪器的超低功耗微控制器MSP430F2013IRSAR已经被昂科的通用烧录平台AP8000所支持。 MSP430F2013IRSAR超低功耗微控制器由多种设备组成&#xff0c;这些设备具有针对各种应…

集体爆雷!突发中科院2区(Top) 被标记!新增10本期刊被“On Hold“

本周投稿推荐 SSCI • 中科院2区&#xff0c;6.0-7.0&#xff08;录用友好&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; CNKI • 7天录用-检索&#xff08;急录友好&#xff09; SCI&EI • 4区生物医学类&#xff0c;0.5-1.0&#xff08;录用…

Nginx缓存之web缓存配置

Web 缓存可节约网络带宽&#xff0c;有效提高用户打开网站的速度。由于应用服务器被请求次数的降低&#xff0c;也相对使它的稳定性得到了提升。Web 缓存从数据内容传输的方向分为前向位置缓存和反向位置缓存两类。如下图所示。 前向位置缓存既可以是用户的客户端浏览器&#x…

处理耗时任务

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 namespace 处理耗时任务 {public partial class Form1 : Form{public Form1(){InitializeComponent();}bool IsRun false;private string path Directory.GetCurrentDirectory() "\\古诗词.txt";private…

Vite+Vue3安装且自动按需引入Element Plus组件库

一&#xff0c;安装Element Plus npm install element-plus //node环境16二&#xff0c;安装插件 npm install unplugin-auto-import unplugin-vue-components -D三&#xff0c;配置vite.config.ts文件 //按需引入element-plus组件 import AutoImport from unplugin-auto-i…

Oracle基本语法

前言&#xff1a; 1.使用的数据库不同&#xff0c;所使用的语法也略有不同 2.SQL对大小写不敏感&#xff0c;无论大小写&#xff0c;sql自动转换为大写 3.用户名、表名、表空间名、文件路径......等需要用单引号将其包含 4.一般引号里面的内容需要大写 准备工作&#xff1a; &a…

0618_QT4

练习&#xff1a; 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和…

性能工具之 JMeter 常用组件介绍(八)

文章目录 一、Jmeter命令行启动二、Jmeter脚本录制 一、Jmeter命令行启动 Jmeter有两种运行&#xff1a; 一种是采用的界面模式(GUI&#xff09;启动&#xff0c;会占用不少系统资源&#xff1b;另一种是命令行模式&#xff08;non-GUI&#xff09;执行&#xff0c;这样节约资…

《SelectDB 新一代日志存储分析平台解决方案》白皮书重磅发布|立即下载

随着信息技术的飞速进步&#xff0c;企业面临着前所未有的系统复杂性和数据挑战。在此背景下&#xff0c;日志数据成为了企业洞察系统内部状态、监控网络安全以及分析业务动态的宝贵资源&#xff0c;构建高效的日志存储与分析平台至关重要。 作为基于 Apache Doris 打造的现代…

使用 AST语法树分析与修改Javascript 代码

1、AST语法树简介 当编写代码分析工具、代码美化工具、网站逆向分析等场景时&#xff0c;通常需要使用AST语法树技术。 比如项目开发过程中常遇到的场景&#xff1a;某个公共函数名需要更改&#xff0c;但被很多文件多处代码调用&#xff0c;手工修改非常容易漏改、改错等&…

【漏洞复现】致远互联FE协作办公平台 ncsubjass SQL注入

0x01 产品简介 致远互联FE协作办公平台是一款为企业提供全方位协同办公解决方案的产品。它集成了多个功能模块&#xff0c;旨在帮助企业实现高效的团队协作、信息共享和文档管理。 0x02 漏洞概述 致远互联FE协作办公平台 ncsubjass.jsp接口处存在SQL注入漏洞,未经身份验证的…

【Linux】环境设置MySQL表名忽略大小写

目录 说明 一、摘要 二、查看服务器上MySQL情况 方式一&#xff1a;通过Linux方式 方式二&#xff1a;借助可视化工具&#xff08;Navicat&#xff09; 三、MySQL设置忽略表名大小写的参数&#xff08;lower_case_table_names&#xff09; 四、网上解决方案 方法一&…

day03 子查询分页存储过程

目录 子查询 介绍&#xff1a; 子查询规范 子查询分类 模糊查询 注意事项和技巧 分页查询 作用&#xff1a; LIMIT关键字使用 指定初始位置 不指定初始位置 分页 视图 介绍&#xff1a; 优点 创建视图 嵌套视图 删除视图 修改视图 更新视图 存储过程 介绍…

RT-Thread PIN设备

RT-Thread PIN设备 RT-Thread PIN设备驱动框架RT-Thread PIN设备驱动层次图RT-Thread PIN设备注册RT-Thread PIN设备注册函数 RT-Thread PIN设备操作函数pin_getpin_modepin_writepin_readpin_attach_irqpin_detach_irqpin_irq_enable PIN设备又叫GPIO设备&#xff0c;是MCU输入…

SpringSecurity-入门代码

创建SpringBoot项目 参考文章&#xff1a; 【环境搭建】使用IDEA创建SpringBoot项目详细步骤_idea创建spring boot项目-CSDN博客 编写helloworld代码 RestController public class HelloController {GetMapping("/hello")public String hello(){return "hel…

深入了解SD-WAN:企业广域网的未来

在讨论SD-WAN之前&#xff0c;我们先来了解一下WAN的基本概念。WAN&#xff08;广域网&#xff09;是一个连接多个地理位置分散的局域网的通信网络。在企业中&#xff0c;WAN通常连接总部、分支机构、托管设施和云服务等多个网络节点。广域网允许用户共享各种应用和服务&#x…

【AI绘画】新手小白看这篇就够啦!国产PS AI插件超好入门!

随着人工智能技术的飞速发展&#xff0c;Photoshop作为设计师们不可或缺的工具&#xff0c;也在不断地融入AI技术&#xff0c;以提升设计效率和效果。最近米兔用了一款AI绘画软件StartAI&#xff0c;被其强大的功能和易用性经验到了&#xff0c;下面跟大家详细分享一下这款ps插…

ViNT: A Foundation Model for Visual Navigation

介绍 现存的问题&#xff1a;预训练的方式在很多领域取得了成功&#xff0c;但是由于环境、平台和应用程序的绝对多样性&#xff0c;因此很难应用在机器人领域。 那么想要做移动机器人的基础模型需要什么&#xff1f; 本文定义了一个机器人领域的基础模型&#xff0c;可以实…

文字炫酷祝福 含魔法代码

效果下图&#xff1a;&#xff08;可自定义显示内容&#xff09; 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initi…

【RK3588/算能/Nvidia智能盒子】AI“值守”,规范新能源汽车充电站停车、烟火及充电乱象

近年来&#xff0c;中国新能源汽车高速发展&#xff0c;产量连续8年位居全球第一。根据中国充电联盟数据&#xff0c;截至2023年6月&#xff0c;新能源汽车保有量1620万辆&#xff0c;全国充电基础设施累计数量为665.2万台&#xff0c;车桩比约2.5:1。 虽然新能源汽车与充电桩供…