netty的编解码

2020-04-13  本文已影响0人  剑道_7ffc

什么是拆包/粘包

TCP 粘包/拆包

半包:读取的数据不是一个数据包
粘包:读取的数据超过一个数据包


image.png

粘包问题的解决策略

业界的主流协议的解决方案
  1. 消息定长,报文大小固定长度,例如每个报文的长度固定为 200 字节,如果不够空位补空格;
  2. 包尾添加特殊分隔符,例如每条报文结束都添加回车换行符(例如 FTP 协议)或者指定特殊字符作为报文分隔符, 接收方通过特殊分隔符切分报文区分;
  3. 将消息分为消息头和消息体,消息头中包含表示信息的总长度(或者消息体长度)的字段;
  4. 更复杂的自定义应用层协议。
netty的解决方案

将 channel 中的数据读取时候经过解析, 如果不是一个完整的数据包, 则解析失败, 将这块数据包进行保存, 等下次解析时再和这个数据包进行组装解析, 直到解析到完整的数据包, 才会将数据包进行向下传递。

什么是编码和解码

编、解码技术

编码:序列化,用于网络传输,数据持久化。
解码:反序列化

Netty 为什么要提供编解码框架?

在保证定制扩展性的基础上,尽量降低用户的开发难度和开发量,提升开发效率。

Netty 中常用的解码器

Netty 默认提供了多个解码器,可以进行分包的操作,满足 99%的编码需求。

如何区分一个整包消息,通常有如下 4 种做法:

  1. 固定长度,例如每 120 个字节代表一个整包消息,不足的前面补位。解码器在处理这类定常消息的时候比较简单, 每次读到指定长度的字节后再进行解码;
  2. 通过回车换行符区分消息,例如 HTTP 协议。这类区分消息的方式多用于文本协议;
  3. 通过特定的分隔符区分整包消息;
  4. 通过在协议头/消息头中设置长度字段来标识整包消息。

ByteToMessageDecoder 抽象解码器

将字节数组编程对象,没有考虑到粘包的问题。
io.netty.handler.codec.ByteToMessageDecoder#channelRead

LineBasedFrameDecoder 行解码器

解码一行

DelimiterBasedFrameDecoder 分隔符解码器

是按照指定分隔符进行解码的解码器, 通过分隔符, 可以将二进制流拆 分成完整的数据包。

FixedLengthFrameDecoder 固定长度解码器

FixedLengthFrameDecoder 固定长度解码器,它能够按照指定的长度对消息进行自动解码,开发者不需要考虑 TCP 的 粘包/拆包等问题,非常实用。

LengthFieldBasedFrameDecoder 通用解码器

通过在协议头/消息头中设置长度字段来标识整包消息。

Netty 编码器原理和数据输出

writeAndFlush 事件传播

将数据写到发送缓存中,同时也能刷新到channel中

MessageToByteEncoder 抽象编码器

将对象编译成字节数组

自定义编、解码

MessageToMessageDecoder 抽象解码器

Netty 的二次解码器,它的职责是将一个对象二次解码为其它对象。

ObjectEncoder 序列化编码器

实现 Serializable 接口的对象序列化为 byte []

LengthFieldPrepender 通用编码器

长度字段通用编码器。

上一篇 下一篇

猜你喜欢

热点阅读