【图解IO与Netty系列】Netty编解码器、TCP粘包拆包问题处理、Netty心跳检测机制

Netty编解码器、TCP粘包拆包问题处理、Netty心跳检测机制

  • Netty编解码器
    • 编码器
    • 解码器
    • 编解码器
    • Netty提供的现成编解码器
  • TCP粘包拆包问题处理
  • Netty心跳检测机制

Netty编解码器

网络传输是以字节流的形式传输的,而我们的应用程序一般不会直接对字节流进行处理,而是把字节流解析成有一定结构的数据格式再去处理。因此我们在发送数据时,要对我们的数据进行编码,把它转换成二进制字节流的形式,然后在网络中进行传输,当我们接收到对方传输过来的二进制字节流时,又需要对其进行解码,解析成应用程序能够处理的数据格式。

比如客户端向服务端发送数据的场景:
在这里插入图片描述

这个编码和解码的动作,可以由用户自己去实现,比如我们使用Java原生的NIO进行开发时,就不得不自己去实现一套编解码的逻辑。而我们使用了Netty之后,Netty给我们封装好了各种编解码器,我们只要使用对应的编解码器,即可以很简单的对数据进行编解码,进一步简化了网络程序的开发。

在这里插入图片描述

编码器

Netty提供了两个编码器抽象类,我们可以选择性的继承它们以实现自己定制的编码器,这两个编码器抽象类分别是MessageToByteEncoder和MessageToMessageEncoder。

  • MessageToByteEncoder<I>:将消息编码为字节
  • MessageToMessageEncoder<T>:将消息编码为消息

它们都继承了ChannelOutboundHandlerAdapter,因此它们都是用于处理出站事件的。

在这里插入图片描述

MessageToByteEncoder的抽象方法encode(ChannelHandlerContext ctx, I msg, ByteBuf out)把特定的类型的消息msg编码成二进制,消息类型由泛型“I”指定。我们继承MessageToByteEncoder后,要实现这个encode方法,encode方法接收指定类型的消息对象msg,然后我们对其进行编码后要放入到ByteBuf类型的out对象中。

在这里插入图片描述

MessageToMessageEncoder的抽象方法encode(ChannelHandlerContext ctx, I msg, ByteBuf out)把特定的类型的消息msg编码成另外一种消息,消息类型由泛型“I”指定。我们继承MessageToMessageEncoder后,要实现这个encode方法,encode方法接收指定类型的消息对象msg,然后我们对其进行编码后要放入到List类型的out对象中。

在这里插入图片描述

比如我们可以通过MessageToMessageEncoder把一个对象转换成json格式的字符串,然后通过MessageToByteEncoder把json字符串加密后编码成二进制字节流。

在这里插入图片描述

解码器

Netty提供了两个解码器抽象类,我们可以选择性的继承它们以实现自己定制的解码器,这两个解码器抽象类分别是ByteToMessageDecoder和MessageToMessageDecoder<I>。

  • ByteToMessageDecoder:将字节解码为消息
  • MessageToMessageDecoder<I>:将一种消息类型解码为另一种

它们都继承了ChannelInboundHandlerAdapter,因此它们都是用来处理入站事件的。

在这里插入图片描述

ByteToMessageDecoder的抽象decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)方法中ByteBuf类型参数in可以获取到接收进来的字节流,我们需要把它解码成特定的对象,然后放入List类型的out中。

在这里插入图片描述

MessageToMessageDecoder中的抽象方法decode(ChannelHandlerContext ctx, I msg, List<Object> out)把特定类型的对象msg解码成另一种类型的对象,然后放入out中。

在这里插入图片描述

比如我们接收到上面这个例子发送的编码后的二进制字节流,我们可以通过ByteToMessageDecoder解码后解密成json字符串,然后通过MessageToMessageDecoder把json字符串转成对象。

在这里插入图片描述

编解码器

Netty还提供了集编码解码一体的编解码器抽象类,它们分别是ByteToMessageCodec和MessageToMessageCodec,它们同时处理入站事件和出站事件。但是我们一般很少使用,更多的是把编码和解码分开两个类,这样才能最大化代码的可重用性和可扩展性。

Netty提供的现成编解码器

上面这些都是抽象类,是需要我们自己继承后实现编解码逻辑的,而Netty还有更牛逼的直接现成的编解码器类提供给我们,我们把它们组装到ChannelPipeline中即可使用。

在这里插入图片描述

根据不同的协议或不同的功能,Netty提供了对应的编码器或解码器,有处理SSL或TLS协议的、有处理HTTP协议的、有做HTTP压缩的、有处理WebSocket协议的等等。这里就不一一细说了,我们只要知道Netty都提供了哪些功能的内置编解码器,再按需的去了解即可。

TCP粘包拆包问题处理

由于TCP是一个面向二进制流的协议,是传输层协议,并不理解应用层传下来的业务数据,但是TCP又会根据MSS对数据进行分包处理,于是会出现下面四种情况:

在这里插入图片描述

  • 第一种情况是TCP分包分的刚刚好,D1和D2两个独立的数据包分开发送,这是没有问题的。
  • 第二种情况就是TCP把D1和D2两个数据包连在一起被TCP一同发送,此时就发生了粘包问题。
  • 第三种情况和第四种情况都是其中一个数据包被分成了两半,与另一个数据包一起一同发送,此时就发生了拆包问题。

当发生TCP粘包拆包问题时,接收数据的一方需要通过某种机制将被拆分或粘连的数据包还原成独立的数据包。

Netty提供了多个解码器可以处理TCP粘包拆包问题:

  • LineBasedFrameDecoder:利用回车换行符做分包处理
  • DelimiterBasedFrameDecoder:利用指定的特殊分隔符做分包处理
  • FixedLengthFrameDecoder:以固定长度来分包
  • LengthFieldBasedFrameDecoder:消息头中记录消息总长度,通过消息头中记录的消息体长度进行分包

这几个都是上面说过的Netty提供的现成解码器。

除此以外我们还可以自己实现TCP粘包拆包的处理:

  1. 我们可以通过实现自己的MessageToByteEncoder将消息编码成二进制时,先写出消息长度再写出消息体
  2. 然后实现ByteToMessageDecoder(或ReplayingDecoder),在解码时先读取一个int,得到消息体长度,然后再读取指定长度的字节流解码成出消息体。

在这里插入图片描述

Netty心跳检测机制

Netty提供了一个IdleStateHandler可以用于进行心跳检测,我们可以设置读超时时间或写超时时间,比如我们设置了读超时时间,IdleStateHandler在指定时间内没有从通道中读取到数据,就会触发一个IdleStateEvent事件,IdleStateEvent中有一个state字段记录是什么类型的超时时间(读超时、写超时、读写超时)。

我们可以在ChannelPipeline添加一个IdleStateHandler,然后我们再继承SimpleChannelInboundHandler实现自定义的入站处理放于IdleStateHandler的后面,就可以在发生读超时或写超时事件时,在userEventTriggered(ChannelHandlerContext ctx, Object evt)方法中接收到IdleStateHandler发出的IdleStateEvent对象,我们就可以进行相应处理,比如读超时事件则进行探活处理或者关闭连接等操作。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

建筑驱鸟设备 | 建筑专用超声波驱鸟器

从半夜的鸣叫到频繁的鸟粪污染&#xff0c;鸟类活动有时会成为城市居民不得不面对的小小困扰。通过合理的驱鸟方法&#xff0c;我们可以有效地减少鸟类对建筑物的侵扰&#xff0c;保护建筑物的完好和安全&#xff0c;同时维护城市居民的生活质量。 建筑专用超声波驱鸟器&#x…

理解 JTBD 框架和EJ 理念:深挖以用户为中心的设计

在与用户的交流中&#xff0c;我们发现对用户需求的精准洞察普遍困扰着产品经理、设计、企划人员&#xff0c;因为当今消费者行为已经由单品消费转向场景消费&#xff0c;千人千面的个性化需求出现&#xff0c;消费者数据维度极大丰富&#xff0c;这对把握用户体验造成了很大挑…

Android开发系列(五)Jetpack Compose之Icon Image

Icon是用于在界面上显示矢量图标的组件。它提供了很多内置的矢量图标&#xff0c;也支持自定义图标。要使用Icon组件&#xff0c;可以通过指定图标资源的名称或引用来创建一个Icon对象。例如&#xff0c;使用Icons.Default.Home来创建一个默认风格的首页图标。可以通过设置图标…

TrueNAS系统在ARM平台上的移植

随着家庭及中小型企业对存储和共享需求的日益增长&#xff0c;高效、可靠的文件存储系统成为支撑各类应用的关键。 在众多存储系统中&#xff0c;TrueNAS以其卓越的数据完整性与可靠性、简洁高效的应用程序部署和管理、灵活的虚拟化应用添加能力&#xff0c;以及出色的可用性&a…

【第24章】Vue实战篇之用户信息展示

文章目录 前言一、准备1. 获取用户信息2. 存储用户信息3. 加载用户信息 二、用户信息1.昵称2.头像 三、展示总结 前言 这里我们来展示用户昵称和头像。 一、准备 1. 获取用户信息 export const userInfoService ()>{return request.get(/user/info) }2. 存储用户信息 i…

【面试题】风险评估和应急响应的工作流程

风险评估和应急响应是网络安全管理中两个重要的环节。下面分别介绍它们的工作流程&#xff1a; 一、风险评估工作流程&#xff1a; 1.确定评估范围&#xff1a;明确需要评估的信息系统或资产的范围。 2.资产识别&#xff1a;识别并列出所有需要评估的资产&#xff0c;包括硬件…

美妆短剧撬动33亿市值后,爆款短剧有了新风向

6月1日起微短剧分级备案正式施行&#xff0c;所有短剧未经备案不得播出&#xff0c;该备案也是短剧行业的首个行业规范&#xff0c;让近两年来肆意增长的短剧迎来新一轮洗牌&#xff0c;在保障短剧质量的同时&#xff0c;也促进了行业的发展。 ▲ 图片来源&#xff1a;网络 面对…

Freertos-----任务之间的消息传递(使用消息队列信号量方法)

这次来分享任务之间的数据传递的方法&#xff0c;方法有很多种&#xff0c;我展示2种&#xff0c;让大家对freertos有更深刻的印象 目录 消息队列 信号量 消息队列 首先直接打开普中的例程&#xff0c;然后在里面加上ADC的驱动代码&#xff0c;先初始化外设先&#xff0c;我…

前端模糊搜索关键字高亮

效果 代码 <template><view class"flexStart new-box"><view class"company"><!-- 输入框样式 --><view class"spaceBetween companyName" click.stop"isCompany true"><input type"text&quo…

xargs 传参

xargs的默认命令是 echo&#xff0c;空格是默认定界符。这意味着通过管道传递给 xargs的输入将会包含换行和空白&#xff0c;不过通过 xargs 的处理&#xff0c;换行和空白将被空格取代。xargs是构建单行命令的重要组件之一。 xargs -n1 // 一次输出一个参数到一行&#xf…

qmt量化交易策略小白学习笔记第47期【qmt编程之期货仓单】

qmt编程之获取期货数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 感谢关注&#xff0c;咨询免费开通量化回测与获取实盘权限&#xff0c;欢迎和博主联系&#xff01; 期货仓单 提示 1…

使用Python selenium爬虫领英数据,并进行AI岗位数据挖掘

随着OpenAI大火&#xff0c;从事AI开发的人趋之若鹜&#xff0c;这次使用Python selenium抓取了领英上几万条岗位薪资数据&#xff0c;并使用Pandas、matplotlib、seaborn等库进行可视化探索分析。 但领英设置了一些反爬措施&#xff0c;对IP进行限制封禁&#xff0c;因此会用到…

mysql 某个时间字段取值时间标识的字符串的值

SELECT STR_TO_DATE(substr(out_trade_no, 1,14), %Y-%m-%d %H:%i:%s) FROM o_order WHERE id 364457; UPDATE o_order SET created_time DATE_FORMAT(STR_TO_DATE(substr(out_trade_no, 1,14), %Y%m%d %H%i%s), %Y-%m-%d %H:%i:%s) WHERE id 364457; 举例&#xff1a; 1…

五种实用方法!手把手教你系统盘瘦身

随着电脑的使用时间变长&#xff0c;电脑硬盘会逐渐被各种类型的数据占满&#xff0c;其中系统盘的可用空间也在慢慢变小。这是因为系统在运行过程中会产生大量临时文件和缓存文件&#xff0c;同时&#xff0c;系统的每一次更新升级也都会生成相关的文件夹存放在系统盘中&#…

高阶图神经网络 (HOGNN) 的概念、分类和比较

图神经网络&#xff08;GNNs&#xff09;是一类强大的深度学习&#xff08;DL&#xff09;模型&#xff0c;用于对相互连接的图数据集进行分类和回归。它们已被用于研究人类互动、分析蛋白质结构、设计化合物、发现药物、识别入侵机器、模拟单词之间的关系、寻找有效的交通路线…

AI/ML 数据湖参考架构架构师指南

这篇文章的缩写版本于 2024 年 3 月 19 日出现在 The New Stack 上。 在企业人工智能中&#xff0c;主要有两种类型的模型&#xff1a;判别模型和生成模型。判别模型用于对数据进行分类或预测&#xff0c;而生成模型用于创建新数据。尽管生成式人工智能最近占据了新闻的主导地…

excel基本操作

excel 若要取消在数据表中进行的所有筛选 步骤操作&#xff1a; 单击“数据”选项卡。在“排序和筛选”组中&#xff0c;找到“清除”按钮。点击“清除”按钮。 图例&#xff1a; 将文本文件的数据导入到Excel工作表中进行数据处理 步骤&#xff1a; 在Excel中&#xff0c…

DevEco鸿蒙开发请求网络交互设置

首先&#xff0c;在鸿蒙项目下config.json中找到module项&#xff0c;在里面填写"reqPermissions": [{"name": "ohos.permission.INTERNET"}] 在页面对应js文件内&#xff0c;填写import fetch from system.fetch;。 GET和POST区别 GET将表单数…

下班时间如何安排?

随着互联网的飞速发展和数字化时代的来临&#xff0c;越来越多的人开始探索除了主业以外的赚钱途径&#xff0c;以增加收入来源。本文将为您介绍几种当前热门的高薪副业项目&#xff0c;包括网络任务赚钱、开设个人网店、电商导购推广、在线辅导教学、技能变现服务、视频创作分…

机械硬盘和固态硬盘的区别及判断硬盘类型的方法

HDD&#xff08;机械硬盘&#xff09;和 SSD&#xff08;固态硬盘&#xff09;的主要区别 存储介质 HDD&#xff1a;使用磁性盘片&#xff08;磁盘&#xff09;和机械读写头SSD&#xff1a;使用闪存芯片 速度 HDD&#xff1a;读写速度较慢&#xff0c;因为需要机械读写头在…