没有合适的资源?快使用搜索试试~ 我知道了~
03-04-10-Netty编解码的艺术1
需积分: 0 0 下载量 154 浏览量
2022-08-04
16:44:42
上传
评论
收藏 925KB PDF 举报
温馨提示
试读
56页
第 5 章Netty 高性能之道第 6 章揭开 BootStrap 的神秘面纱第 7 章大名鼎鼎的 EventLoop第 8 章Netty 大动脉 Pipeli
资源详情
资源评论
资源推荐
咕泡出品,必属精品 www.gupaoedu.com
1
第 3 篇
Netty 核心篇
第 5 章 Netty 高性能之道
第 6 章 揭开 BootStrap 的神秘面纱
第 7 章 大名鼎鼎的 EventLoop
第 8 章 Netty 大动脉 Pipeline
第 9 章 Promise 与 Future 双子星的秘密
第 10 章 Netty 内存分配 ByteBuf
第 11 章 Netty 编解码的艺术
3
咕泡出品,必属精品 www.gupaoedu.com
2
第 11 章
Netty 编解码的艺术
课程目标
1、。
2、。
3、。
内容定位
1.。
2.。
11
咕泡出品,必属精品 www.gupaoedu.com
3
在前面的章节有一个遗留问题, 就是如果 Server 在读取客户端的数据的时候, 如果一次读取不完整, 就触发
channelRead 事件, 那么 Netty 是如何处理这类问题的, 本章会对此做详细剖析。
11.1 什么是拆包/粘包
11.1.1 TCP 粘包/拆包
TCP 是一个“流”协议,所谓流,就是没有界限的一长串二进制数据。TCP 作为传输层协议并不不了解上层业务数据的具
体含义,它会根据 TCP 缓冲区的实际情况进行数据包的划分,所以在业务上认为是一个完整的包,可能会被 TCP 拆分
成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的 TCP 粘包和拆包问题。
同样, 在 Netty 的编码器中, 也会对半包和粘包问题做相应的处理。什么是半包, 顾名思义, 就是不完整的数据包, 因为
Betty 在轮询读事件的时候, 每次将 channel 中读取的数据, 不一定是一个完整的数据包, 这种情况, 就叫半包。粘包同
样也不难理解, 如果 Client 往 Server 发送数据包, 如果发送频繁很有可能会将多个数据包的数据都发送到通道中, 如果
在 server 在读取的时候可能会读取到超过一个完整数据包的长度, 这种情况叫粘包。有关半包和粘包, 如下图所示:
11.1.2 粘包问题的解决策略
由于底层的 TCP 无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层
的应用协议栈设计来解决。业界的主流协议的解决方案,可以归纳如下:
咕泡出品,必属精品 www.gupaoedu.com
4
1. 消息定长,报文大小固定长度,例如每个报文的长度固定为 200 字节,如果不够空位补空格;
2. 包尾添加特殊分隔符,例如每条报文结束都添加回车换行符(例如 FTP 协议)或者指定特殊字符作为报文分隔符,
接收方通过特殊分隔符切分报文区分;
3. 将消息分为消息头和消息体,消息头中包含表示信息的总长度(或者消息体长度)的字段;
4. 更复杂的自定义应用层协议。
Netty 对半包的或者粘包的处理其实也很简单, 通过之前的学习, 我们知道, 每个 handler 是和 channel 唯一绑定的, 一
个 handler 只对应一个 channel, 所以将 channel 中的数据读取时候经过解析, 如果不是一个完整的数据包, 则解析失
败, 将这块数据包进行保存, 等下次解析时再和这个数据包进行组装解析, 直到解析到完整的数据包, 才会将数据包进
行向下传递。
11.2 什么是编码和解码
11.2.1 编、解码技术
通常我们也习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输、数据持
久化或者其它用途。反之,解码(Decode)/反序列化(deserialization)把从网络、磁盘等读取的字节数组还原成原
始对象(通常是原始对象的拷贝),以方便后续的业务逻辑操作。进行远程跨进程服务调用时(例如 RPC 调用),需
要使用特定的编解码技术,对需要进行网络传输的对象做编码或者解码,以便完成远程调用。
11.2.2 Netty 为什么要提供编解码框架?
作为一个高性能的异步、NIO 通信框架,编解码框架是 Netty 的重要组成部分。尽管站在微内核的角度看,编解码框
架并不是 Netty 微内核的组成部分,但是通过 ChannelHandler 定制扩展出的编解码框架却是不可或缺的。
然而,我们已经知道在 Netty 中,从网络读取的 Inbound 消息,需要经过解码,将二进制的数据报转换成应用层协议
消息或者业务消息,才能够被上层的应用逻辑识别和处理;同理,用户发送到网络的 Outbound 业务消息,需要经过
咕泡出品,必属精品 www.gupaoedu.com
5
编码转换成二进制字节数组(对于 Netty 就是 ByteBuf)才能够发送到网络对端。编码和解码功能是 NIO 框架的有机
组成部分,无论是由业务定制扩展实现,还是 NIO 框架内置编解码能力,该功能是必不可少的。
为了降低用户的开发难度,Netty 对常用的功能和 API 做了装饰,以屏蔽底层的实现细节。编解码功能的定制,对于熟
悉 Netty 底层实现的开发者而言,直接基于 ChannelHandler 扩展开发,难度并不是很大。但是对于大多数初学者或者
不愿意去了解底层实现细节的用户,需要提供给他们更简单的类库和 API,而不是 ChannelHandler。
Netty 在这方面做得非常出色,针对编解码功能,它既提供了通用的编解码框架供用户扩展,又提供了常用的编解码类
库供用户直接使用。在保证定制扩展性的基础之上,尽量降低用户的开发工作量和开发门槛,提升开发效率。
Netty 预置的编解码功能列表如下:Base64、Protobuf、JBoss Marshalling、Spdy 等。
11.3 Netty 中常用的解码器
Netty 默认提供了多个解码器,可以进行分包的操作,满足 99%的编码需求。
11.3.1 ByteToMessageDecoder 抽象解码器
使用 NIO 进行网络编程时,往往需要将读取到的字节数组或者字节缓冲区解码为业务可以使用的 POJO 对象。为了方
便业务将 ByteBuf 解码成业务 POJO 对象,Netty 提供了 ByteToMessageDecoder 抽象工具解码类。
用户自定义解码器继承 ByteToMessageDecoder,只需要实现 void decode(ChannelHandler Context ctx, ByteBuf in,
剩余55页未读,继续阅读
小小二-yan
- 粉丝: 26
- 资源: 299
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0