完善 TCP粘拆包问题及Netty中的解决方案.md 的内容

pull/30/head
AmyliaY 5 years ago
parent 973334a0b6
commit 06be4c61df

@ -20,23 +20,17 @@ TCP 是个 “流” 协议所谓流就是没有界限的一串数据。TC
2. 进行 MSS 大小的 TCP分段
3. 以太网帧的 payload 大于 MTU 进行 IP分片。
### 粘包问题的解决策略
### 粘包问题的解决策略
由于底层的 TCP 无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界的主流协议的解决方案,可以归纳如下。
1. 消息例如每个报文的大小为固定长度200字节如果不够空位补空格
2. 在包尾增加回车换行符进行分割例如FTP协议
3. 将消息分为消息头和消息体,消息头中包含表示消息总长度 (或者消息体长度) 的字段,通常设计思路为消息头的第一个字段使用 int32 来表示消息的总长度;
1. 固定消息长,例如每个报文的大小为 固定长度200字节如果不够空位补空格
2. 在包尾使用 “回车换行符” 等特殊字符作为消息结束的标志例如FTP协议这种方式在文本协议中应用比较广泛
3. 将消息分为消息头和消息体,在消息头中定义一个 长度字段Len 来标识消息的总长度;
4. 更复杂的应用层协议。
介绍完了 TCP粘包/拆包 的基础,下面我们来看看 Netty 是如何使用一系列 “半包解码器” 来解决 TCP粘包/拆包问题的。
## 利用 Netty的解码器 解决 TCP粘拆包问题
TCP 以流的方式进行数据传输上层应用协议为了对消息进行区分往往采用如下4种方式。
1. 固定消息长度,累计读取到长度总和为 定长Len 的报文后,就认为读取到了一个完整的消息,将计数器置位,重新开始读取下一个数据报;
2. 将 “回车换行符” 作为消息结束符,例如 FTP协议这种方式在文本协议中应用比较广泛
3. 将特殊的分隔符作为消息的结束标志,回车换行符是特殊的结束分隔符之一;
4. 在消息头中定义一个 长度字段Len 来标识消息的总长度。
Netty 对上面4种应用做了统一的抽象提供了4种解码器来解决对应的问题。有了这些解码器用户不需要自己对读取的报文进行人工解码也不需要考虑TCP的粘包和拆包。
根据上面的 粘拆包问题解决策略Netty 提供了相应的解码器实现。有了这些解码器用户不需要自己对读取的报文进行人工解码也不需要考虑TCP的粘包和拆包。
### LineBasedFrameDecoder 和 StringDecoder 的原理分析
为了解决 TCP粘包 / 拆包 导致的 半包读写问题Netty 默认提供了多种编解码器用于处理半包只要能熟练掌握这些类库的使用TCP粘拆包问题 从此会变得非常容易,你甚至不需要关心它们,这也是其他 NIO框架 和 JDK原生的 NIO API 所无法匹敌的。对于使用者来说,只要将支持半包解码的 Handler 添加到 ChannelPipeline对象 中即可,不需要写额外的代码,使用起来非常简单。

Loading…
Cancel
Save