网站首页 > 技术文章 正文
前言
在之前我们将结果什么是粘包和半包, 通常情况下我们想解决这种TCP消息传输问题都会采用固定消息头或者固定长度的方式, 在Netty中当然也有相应的方法, 本章主要讲解Netty中的解码器ByteToMessageDecoder
在Netty中, 每个handler和channel都是唯一绑定的, 一个handler只对应一个channel, 所以在将channel中的数据进行解析时, 若不是一个完整的数据包则解析失败, 并将这个数据包进行保存, 等下次解析时对两个数据进行组合解析, 直到解析到完整的数据, 才会将数据包进行向下传递
本篇文章将添加于我的Netty专栏 欢迎大家关注
ByteToMessageDecoder
可以看到该类是个抽象类, 也是Netty解码器的基类, 所以我们在实际使用解码器时一般也不是直接使用的该类, 而是使用的其子类
继承实现图
通过继承实现图可以看到该类继承于ChannelInboundHandler属于入站类Handler, 是专门用来处理输入的Handler
Cumulator 累加器
在这个类最开始映入眼帘的就是两个累加器
MERGE_CUMULATOR: 通过内存拷贝把数据都放入一个ByteBuf里面
COMPOSITE_CUMULATOR: 混合存储, 相当于将ByteBuf加入到CompositeByteBuf中, 同时因为使用了更复杂的索引计算, 所以他会比MERGE_CUMULATOR更慢
channelRead() 方法
这是一个入站Handler所以我们还是主要看他的channelRead()方法
在该方法中, 流程大概如下:
- 首先去判断这个消息是否为ByteBuf类型
- 将变量selfFiredChannelRead设置为true, 这个变量一共调用了两次, 一次是这回的赋值, 下一次是在通道读取完成的时候调用的方法
接下来 CodecOutputList out =
CodecOutputList.newInstance(); 可以理解为创建了一个List, 用于存储解析到的对象, 这个类CodecOutputList的继承实现图如下所示, 可以看到他继承了List类
然后去判断当前累加器是否为null, 如果为null, 则first == true, 代表这是第一次从IO流中读取数据, 执行cumulator.cumulate方法, 这个方法是个接口, 他的作用如下
- first == true, 则将刚读进来的数据赋值给累加器
- first == false, 则将累加器内的数据和当前数据进行累加
最后会执 行callDecode(ctx, cumulation, out); 进行解析
当我们执行完累加器操作之后, 会进入到finally内
在这里会进行累加器的判断, 如果累计区没有可读字节了就将numReads次数归零, 释放累计去, 等待GC
但是如果当前累加器内还有数据, 就会进行numReads++操作, 当numReads > 16时, 会将已经读过的数据进行丢弃, 同时numReads = 0
最后记录list长度, firedChannelRead |= out.insertSinceRecycled(); 这一步是判断是否已回收, 只有当firedChannelRead和out.insertSinceRecycled()均为false时为firedChannelRead == false, 其他情况均为ture
最后向下传播数据
本文内容到此结束了
如有收获欢迎点赞收藏关注,您的鼓励是我最大的动力。
作者:宁轩
链接:
https://juejin.cn/post/7179755582218305591
猜你喜欢
- 2025-07-08 css实现的卡片式渐变色卡html页面前端源码
- 2025-07-08 css实现的图片悬停旋转弹出文本框html页面前端源码
- 2025-07-08 宝塔搭建实战人才求职管理系统member用户前端vue源码(四)
- 2025-07-08 宝塔搭建实战人才求职管理系统admin前端vue源码(二)
- 2024-10-11 JavaScript实现的转盘抽奖html页面前端源码
- 2024-10-11 前端录屏 + 定位源码,帮你快速定位线上 bug
- 2024-10-11 css+JavaScript实现的二级导航菜单html页面前端源码
- 2024-10-11 交互问卷表单设计html页面前端源码
- 2024-10-11 web前端实战项目(免费送源码+视频)
- 2024-10-11 html5+css3做的响应式企业网站前端源码
你 发表评论:
欢迎- 07-08记oracle日志挖掘实操&查询归档不正常增长情况(一)
- 07-08Oracle 伪列!这些隐藏用法你都知道吗?
- 07-08orcl数据库查询重复数据及删除重复数据方法
- 07-08重大故障!业务核心表被truncate删除,准备跑路……
- 07-08oracle数据恢复—oracle执行truncate命令误删除数据的数据恢复
- 07-08Oracle-rac 修改scanip(oracle 修改sequence cache)
- 07-08ORACLE RAC CDB和PDB切换(oracle数据库rac切换)
- 07-08Oracle rac haip作用(oracle rac的典型特征)
- 596℃几个Oracle空值处理函数 oracle处理null值的函数
- 589℃Oracle分析函数之Lag和Lead()使用
- 576℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 573℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 569℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 562℃【数据统计分析】详解Oracle分组函数之CUBE
- 549℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 542℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- 记oracle日志挖掘实操&查询归档不正常增长情况(一)
- Oracle 伪列!这些隐藏用法你都知道吗?
- orcl数据库查询重复数据及删除重复数据方法
- 重大故障!业务核心表被truncate删除,准备跑路……
- oracle数据恢复—oracle执行truncate命令误删除数据的数据恢复
- Oracle-rac 修改scanip(oracle 修改sequence cache)
- ORACLE RAC CDB和PDB切换(oracle数据库rac切换)
- Oracle rac haip作用(oracle rac的典型特征)
- 新手小白怎么学UI设计 推荐学习路线是什么
- 超实用!0基础UI设计自学指南(0基础学ui设计好就业吗)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端懒加载 (49)
- 前端获取当前时间 (50)
- 前端接口 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle的函数 (57)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)