DotNetty ByteBuffer

DotNetty是一个高性能的.NET网络通信框架,基于Netty,支持TCP、UDP、HTTP、WebSocket等协议。适用于高并发、低延迟场景,如实时通信、游戏服务器、IoT应用及大型分布式系统,通过异步I/O、零拷贝等技术提升性能,具备易用性、可扩展性。
架构上,围绕Channel、EventLoop、ChannelPipeline、ChannelHandlerContext设计,包含Transport、Codec、Handler等模块,简化网络编程,加速数据传输处理。

ByteBuffer 用于高效处理字节数据,固定容量,通过allocate或wrap创建。涉及position和limit追踪读写位置,提供get/put等读写方法,flip切换读写模式,clear清空缓冲区,compact移动数据并准备下一轮读写,适用于高性能IO与网络通信。.

优点
零拷贝通过复合缓冲区实现。
动态容量增长。
无需flip切换读写模式。
分离读写索引。
内置引用计数。
支持缓冲区池化。
优化网络通信中的字节处理。

结构
readerIndex 读取,随读增。
writerIndex 写入,随写增。
capacity容量。
在这里插入图片描述
ByteBuffer属性
readIndex:下一个读位
writeIndex:下一个写位置
capacity:容量
0:缓冲区开始位置

已经读取的区域:[0,readerindex)
可读取的区域:[readerindex,writerIndex)
可写的区域: [writerIndex,capacity)
读写独立索引,操作命名区分(read/write自动进,get/set不影响索引)。
支持设定最大容量,超限写操作将抛异常,默认上限Integer.MAX_VALUE。
readerIndex writerIndex 本质为灵活高效字节容器

堆缓冲区
最常用的 ByteBuffer 模式是将数据存储在堆空间中。这种模式被称为支撑数组(backing array),它能在没有使用池化的情况下提供快速的分配和释放。可以由 hasArray() 来判断检查 ByteBuffer是否由数组支撑。如果不是,则这是一个直接缓冲区。

直接缓冲区
直接缓冲区是另外一种 ByteBuffer 模式。
直接缓冲区的主要缺点是,相对于基于堆的缓冲区,它们的分配和释放都较为昂贵。

复合缓冲区
复合缓冲区 CompositeByteBuf,它为多个 ByteBuffer提供一个聚合视图。比如 HTTP 协议, 分为消息头和消息体,这两部分可能由应用程序的不同模块产生,各有各的 ByteBuffer,将会在消息被发送的时候组装为一个 ByteBuffer,此时可以将这两个 ByteBuffer聚合为一个 CompositeByteBuf,然后使用统一和通用的 ByteBuffer API 来操作。

如何在的程序中获得 ByteBuf 的实例,并使用它呢?Netty 提供了两种方式

ByteBufAllocator 接口
ByteBufAllocator 分配任意类型的 ByteBuffer 实例。

buffer(): 基于堆/直接内存ByteBuffer。
heapBuffer(): 仅堆内存。
directBuffer(): 仅直接内存。
compositeBuffer(): 可组合多个缓冲区,支持堆/直接内存。
ioBuffer(): 适配I/O操作,优先直接内存(需Unsafe支持)。
ByteBufAllocator:
Channel ChannelHandlerContext

Unpooled 缓冲区

Unpooled工具类助创ByteBuffer
buffer():堆内存ByteBuffer
directBuffer():直接内存ByteBuffer
wrappedBuffer():包装数据的ByteBuffer
copiedBuffer():复制数据的ByteBuffer 适用范围广泛,不仅限于Netty网络项目。

 IByteBuffer byteBuf = Unpooled.CopiedBuffer("hello,world!", Encoding.UTF8); 

ByteBuf访问/读写
索引从0开始至capacity()-1。
随机访问(get/set)不改索引,需显式调用readerIndex()/writerIndex()移动。
顺序访问分两类:
get/set:固定索引,读写数据不移位。
read/write:自动调整readerIndex/writerIndex。

isReadable() 如果至少有一个字节可供读取,则返回 true
isWritable() 如果至少有一个字节可被写入,则返回 true
readableBytes() 返回可被读取的字节数
writableBytes() 返回可被写入的字节数
capacity() 返回 ByteBuffer 可容纳的字节数。在此之后,它会尝试再次扩展直到达到
maxCapacity()
maxCapacity() 返回 ByteBuffer 可以容纳的最大字节数
hasArray() 如果 ByteBuffer 由一个字节数组支撑,则返回 true
array() 如果 ByteBuffer 由一个字节数组支撑则返回该数组

可丢弃字节
读操作后,字节积累在"可丢弃"段,始于readerIndex。
discardReadBytes()释放已读字节,回收空间,可能导致之前数据移动。
此操作可能涉及内存复制,谨慎使用。

在这里插入图片描述

可读字节:存储实际数据,新缓冲区默认从readerIndex=0开始。
可写字节:空白区域待写入,新缓冲区writerIndex初设0,写操作后自动递增。
在这里插入图片描述

资源释放
处理Netty入站ByteBuffer ,可选自动释放:用SimpleChannelInboundHandler,或在channelRead()末手动调用ReferenceCountUtil.release(msg)确保资源管理。

using DotNetty.Buffers;
using DotNetty.Transport.Channels;public class CommanChannelInboundHandler : SimpleChannelInboundHandler<object>
{protected override void ChannelRead(IChannelHandlerContext context, object message){bool shouldRelease = true;try{if (IsMessageAcceptable(message)){ChannelRead0(context, message);}else{shouldRelease = false;context.FireChannelRead(message);}}finally{if (AutoRelease && shouldRelease){ResourceUtil.Release(message);}}}private bool IsMessageAcceptable(object msg){return msg is IByteBuffer; // 假设只处理IByteBuffer类型的消息}protected virtual void ChannelRead0(IChannelHandlerContext context, object message){//IByteBuffer ...}private bool AutoRelease { get; set; } = true;
}

对于出站请求,不管 ByteBuffer 是否由我们的业务创建的,当调用了 write 或者 writeAndFlush 方法后,Netty 会自动替我们释放,不需要我们业务代码自行释放。

   // 创建ByteBuf对象,初始容量为1,内部动态扩容以容纳更多数据IByteBuffer byteBuf = Unpooled.Buffer(1);Console.WriteLine("byteBuf=" + byteBuf);for (int i = 0; i < 8; i++){byteBuf.WriteByte(i);}Console.WriteLine("byteBuf=" + byteBuf);for (int i = 0; i < 5; i++){Console.WriteLine(byteBuf.GetByte(i));}Console.WriteLine("byteBuf=" + byteBuf);for (int i = 0; i < 5; i++){Console.WriteLine(byteBuf.ReadByte());}Console.WriteLine("byteBuf=" + byteBuf);//byteBuf2// 使用Unpooled工具类创建ByteBuf,内容为"hello,world!"IByteBuffer byteBuf2 = Unpooled.CopiedBuffer("hello,world!", Encoding.UTF8); // Unpooled.CopiedBuffer("hello,world!", Encoding.UTF8);// 使用相关的方法if (byteBuf2.HasArray) // if (byteBuf2.HasArray){byte[] content = byteBuf2.Array;// 将content转成字符串Console.WriteLine(Encoding.UTF8.GetString(content));Console.WriteLine("byteBuf2=" + byteBuf2);Console.WriteLine(byteBuf2.GetByte(0)); // 获取数组0这个位置的字符'h'的ASCII码,h=104int len = byteBuf2.ReadableBytes; // 可读的字节数 12Console.WriteLine("len=" + len);// 使用for取出各个字节并转换为对应的字符打印for (int i = 0; i < len; i++){Console.WriteLine((char)byteBuf2.GetByte(i));}// 范围读取Console.WriteLine(byteBuf2.GetCharSequence(0, 6, Encoding.UTF8));Console.WriteLine(byteBuf2.GetCharSequence(6, 6, Encoding.UTF8));}//byteBuf3 WrappedBuffervar str1 = Encoding.UTF8.GetBytes("hello,world!");var byteBuf3 = Unpooled.WrappedBuffer(str1);if (byteBuf3.HasArray) // if (byteBuf2.HasArray){byte[] content = byteBuf3.Array;// 将content转成字符串Console.WriteLine(Encoding.UTF8.GetString(content));Console.WriteLine("byteBuf3=" + byteBuf3);Console.WriteLine(byteBuf3.GetByte(0)); // 获取数组0这个位置的字符'h'的ASCII码,h=104int len = byteBuf3.ReadableBytes; // 可读的字节数 12Console.WriteLine("len=" + len);// 使用for取出各个字节并转换为对应的字符打印for (int i = 0; i < len; i++){Console.WriteLine((char)byteBuf3.GetByte(i));}// 范围读取Console.WriteLine(byteBuf3.GetCharSequence(0, 6, Encoding.UTF8));Console.WriteLine(byteBuf3.GetCharSequence(6, 6, Encoding.UTF8));}

结果得出 get操作 readerIndex 不变,read操作使其移动。

End

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

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

相关文章

【3.vi编辑器使用(上)】

一、vi编辑器的三种模式及切换命令 1、vi是linux中最基本的编辑器。但vi编辑器在系统管理、服务器配置工作中永远都是无可替代的。 2、vi编辑器的三种模式&#xff1a;命令行模式、插入模式、底行模式。 &#xff08;1&#xff09;命令行模式&#xff1a;用户在用vi编辑文件…

智能变革:领域大模型重塑企业知识管理!

在如今知识密集型的行业领域里&#xff0c;企业员工每天都要与海量的文档和信息打交道&#xff0c;工作邮箱里充斥着无数邮件&#xff0c;办公桌上堆满了各种报告和文档&#xff0c;而每一个文件里都可能藏有关键信息。 然而&#xff0c;要从这些杂乱无章的信息海洋中找到需要…

AI生成四季变化解决方案,四季之美,一图尽揽

随着AI技术已经渗透到我们生活的方方面面&#xff0c;在这个充满变化的时代&#xff0c;美摄科技以其前沿的AI生成技术&#xff0c;为企业带来了全新的视觉体验——AI生成四季变化解决方案。这一方案不仅能够让车辆实拍的照片焕发不同季节的风采&#xff0c;更能在不改变原图构…

【Windows配置nginx开机自启】

Windows配置nginx开机自启 方式一&#xff1a;将nginx加入到windows服务中方式二&#xff1a;通过windows任务计划设定nginx开机自启 方式一&#xff1a;将nginx加入到windows服务中 下载window service wraper&#xff08;https://github.com/winsw/winsw/releases&#xff0…

C++ 进阶(3)虚函数表解析

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 请多多指教&#xff01; 目录 一、虚函数表 二、单继承&#xff08;无虚函数覆盖&#xff09; 继承关系表&#xff1a; 对于实例&#xff1a;derive d 的虚函数表&#xff1a; 对于实例&#xff1a;b…

QT系列教程(5) 模态对话框消息传递

模态对话框接受和拒绝消息 我们创建一个模态对话框&#xff0c;调用exec函数后可以根据其返回值进行不同的处理&#xff0c;exec的返回值有两种&#xff0c;Qt的官方文档记录的为 QDialog::Accepted QDialog::RejectedAccepted 表示接受消息&#xff0c; Rejected表示拒绝消息…

如何将前端项目打包并部署到不同服务器环境

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈&#xff08;笔记是根据b站尚硅谷的前端讲师【张天禹老师】整理的&#xff0c;用于自己复盘&#xff0c;有需要学习的可以去b站学习原版视频&…

wxPython Demo大全系列:ActivityIndicator控件分析

一、ActivityIndicator介绍 wx.ActivityIndicator 控件是 wxPython 中用于显示活动指示器的控件&#xff0c;通常用于指示程序正在执行某些后台任务或操作。它在用户界面中以动画的形式表现出活动状态&#xff0c;让用户知道应用程序正在进行处理而不是被挂起。 主要特点 可视…

数据源不同?奥威BI软件是这么做的

面对数据源不同的情况&#xff0c;BI&#xff08;商业智能&#xff09;软件如奥威BI软件通常通过一系列技术和方法来实现数据的整理。以下以奥威BI软件为例&#xff0c;详细解释其如何整理不同数据源的数据&#xff1a; 数据收集&#xff1a; 爬虫技术&#xff1a;奥威BI软件…

透视AI技术:探索折射技术在去衣应用中的奥秘

引言&#xff1a; 随着人工智能技术的飞速发展&#xff0c;其在图像处理和计算机视觉领域的应用日益广泛。其中&#xff0c;AI去衣技术作为一种颇具争议的应用&#xff0c;引发了广泛的讨论和关注。本文将深入探讨折射技术在AI去衣中的应用及其背后的原理。 一、AI去衣技术简介…

精通Java异常机制,写出高质量代码

作为一名Java开发人员&#xff0c;异常处理是一个无法回避的话题。无论你是初学者还是老手&#xff0c;精通异常处理对于写出高质量、可维护的代码至关重要。今天&#xff0c;我将与大家分享关于Java异常处理的一切&#xff0c;助你在代码质量的道路上突飞猛进! 一、什么是异常…

打造云计算时代的仿真软件

2024年5月25日&#xff0c;北京云道智造科技有限公司&#xff08;下称“云道智造”&#xff09;在深圳成功举办了2024新品发布会暨用户大会。来自全国各地的近500位客户和合作伙伴代表齐聚一堂&#xff0c;共同见证了云道智造新产品的隆重发布&#xff0c;交流分享了仿真领域的…

2024-05-29 blue-VH-driver-对外接口的并行调用-设计与思考

摘要: VH的driver的对外接口, 要做到可以并行&#xff0c;也就是两个不同的线程&#xff0c;分别调用&#xff0c;不能互相阻塞。 本文记录对其的思考和设计。 上下文: 2024-05-28 blue-VH-driver-需求分析及问题分析-CSDN博客 2024-05-27 blue-vh-问题点-CSDN博客 2024-05…

Wpf 使用 Prism 实战开发Day28

首页汇总方块点击导航功能 点击首页汇总方块的时候&#xff0c;跳转到对应的数据页面 step1: 在IndexViewModel 中&#xff0c;给TaskBar 里面Target 属性&#xff0c;赋上要跳转的页面 step2: 创建导航事件命令和方法实现 step3: 实现导航的逻辑。通过取到 IRegionManager 的…

免费,Python蓝桥杯等级考试真题--第17级(含答案解析和代码)

Python蓝桥杯等级考试真题–第17级 一、 选择题 答案&#xff1a;B 解析&#xff1a;&#xff08;x-y&#xff09;%25%21&#xff0c;故答案为B。 答案&#xff1a;B 解析&#xff1a;x16&#xff0c;所以i的值为range&#xff08;1,16&#xff09;&#xff0c;取值为1-15&…

OpenMV学习笔记2——颜色识别

目录 一、打开单颜色识别实例代码 二、代码基础部分 三、阈值选择 四、给识别到的颜色画框 五、多颜色识别 一、打开单颜色识别实例代码 如图&#xff0c;双击打开对应文件即可进入实例代码。 二、代码基础部分 # Single Color RGB565 Blob Tracking Example # # This e…

手机拍照扫描成电子版,这三款软件助你轻松搞定!

在数字化时代&#xff0c;将手机拍照的内容快速转换为电子版已经成为许多人日常生活和工作中不可或缺的技能。无论是快速记录文档、合同&#xff0c;还是将纸质照片、笔记转化为电子格式&#xff0c;手机拍照扫描功能都为我们提供了极大的便利。今天&#xff0c;就为大家介绍三…

11.任务状态查询API函数总结

一、任务相关 API 函数预览 二、任务相关 API 函数详解 1. 函数 uxTaskPriorityGet() 此函数用于获取指定任务的任务优先级&#xff0c;若使用此函数&#xff0c;需在 FreeRTOSConfig.h 文件中设 置配置项 INCLUDE_uxTaskPriorityGet 为 1&#xff0c;此函数的函数原型如下所示…

mybatis异常:Invalid bound statement (not found): com.lm.mapper.ArticleMapper.list

现象&#xff1a; 原因&#xff1a; 无效绑定&#xff0c;应该是mybatis最常见的一个异常了&#xff0c;接口与XML文件没绑定。首先&#xff0c;mapper接口并没有实现类&#xff0c;所以框架会通过JDK动态代理代理模式获取接口的代理实现类&#xff0c;进而根据接口全限定类名…

适合多种苛刻环境的惯性测量单元M-G370PDS

全球IMU市场d在汽车和机器人技术进步和不断增长的应用需求&#xff0c;保持着高速增长的趋势&#xff0c;其中航空航天、国防和汽车等行业对高精度、稳定和紧凑的IMU需求尤为强烈&#xff0c;这些行业对精度和可靠性的高要求直接影响了相关技术的发展方向。 爱普生惯性测量单…