Netty 解决 TCP 粘包或半包问题

所谓 TCP 粘包就是接收端接收到的消息数据不能完整地体现发送端的消息数据。TCP 协议存在粘包的主要原因是 TCP 以“流”的方式来消息处理数据,而“流”是没有界限的一串消息数据。TCP 粘包通常在“流”传输中出现,而 UDP 协议有消息边界,UDP 不会出现粘包问题。

处理 TCP 粘包的唯一方法就是制定应用层的数据通讯协议,通过协议来规范现有接收的数据是否满足消息数据的需要。

为了解决网络数据流的拆包粘包问题,Netty 为我们内置了如下的解码器:

ByteToMessageDecoder
MessageToMessageDecoder
LineBasedFrameDecoder
StringDecoder
DelimiterBasedFrameDecoder
FixedLengthFrameDecoder
ProtoBufVarint32FrameDecoder
ProtobufDecoder
LengthFieldBasedFrameDecoder

Netty 还内置了如下的编码器:

ProtobufEncoder
MessageToByteEncoder
MessageToMessageEncoder
LengthFieldPrepender

ByteToMessageDecoder

如果我们自己想要实现自己的半包解码器,我们可以继承 ByteToMessageDecoder,实现更加复杂的半包解码:

public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter

我们只需要继承该类并实现

protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception;

MessageToMessageDecoder

MessageToMessageDecoder 一般作为二次解码器,当我们在 ByteToMessageDecoder 将一个 bytes 数组转换成一个 java 对象的时候,我们可能还需要将这个对象进行二次解码成其他对象,我们就可以继承这个类

public abstract class MessageToMessageDecoder<I> extends ChannelInboundHandlerAdapter

然后实现

protected abstract void decode(ChannelHandlerContext ctx, I msg, List<Object> out) throws Exception;

LineBasedFrameDecoder

通过在包尾添加回车换行符 \r\n 来区分整包消息。

This chapter requires login to view full content. You are viewing a preview.

Login to View Full Content

Course Curriculum

3

框架与 I/O:Spring、Netty 与 Web 容器

理解 Spring Boot 自动装配、AOP 与事务原理,掌握 Netty Reactor 模型及 Tomcat 连接处理机制,构建高内聚、易扩展的应用服务层。
4

高性能中间件:消息、缓存与存储

熟练运用 MySQL 索引/事务、Redis 缓存策略、Kafka/RocketMQ 消息可靠性,以及 ZooKeeper 分布式协调,搭建稳定、解耦的分布式数据底座。
6

云原生:容器化、可观测性与工程效能

通过 Docker/K8s 实现弹性部署,集成 Metrics/Logs/Traces 构建可观测体系,推动 DevOps 与自动化,让架构在云上持续交付与进化。