Netty源码阅读程序员

TCP粘包/拆包问题和Netty的解决方案

2017-04-26  本文已影响330人  BlackManba_24

什么是TCP协议?

TCP(Transmission Control Protocol传输控制协议)是Internet协议组的主要协议之一。起源于初始的网络实现,补充了IP协议。因此通常称为TCP/IP协议。TCP在运行在IP通信网络的应用程序之间提供稳定的、有序的和错误检查的8字节流分发功能。—— from wiki

什么是TCP的粘包和拆包问题?

TCP是一个“流”协议,所谓流,就是没有边界的一串数据。TCP底层不了解业务数据的含义,只是按照缓冲区的情况进行包的划分,那么业务上一个完整的数据包有可能被划分成多个包发出,也可能多个包被合并成一个数据包发出,这就是TCP的粘包和拆包问题。

如何解决粘包和拆包问题?

TCP不知道数据包的业务含义,所以只能通过上层协议栈的设计来结局,主流方案:

定长消息,消息长度是固定的,不够的进行补齐

特殊字符分隔,如FTP协议在包尾添加换行符进行分隔

将消息分为消息投和消息体,消息头中包含消息的总长,如前4个字节表示整个消息的长度(最灵活和常用的方案)

Netty对粘包和拆包问题的处理

Netty对解决粘包和拆包的方案做了抽象,提供了一些解码器(Decoder)来解决粘包和拆包的问题。如:

LineBasedFrameDecoder:以行为单位进行数据包的解码

DelimiterBasedFrameDecoder:以特殊的符号作为分隔来进行数据包的解码

FixedLengthFrameDecoder:以固定长度进行数据包的解码

LenghtFieldBasedFrameDecode:适用于消息头包含消息长度的协议(最常用)

所以对使用Netty进行网络读写的程序,可以直接使用这些Decoder来完成数据包的解码。

由于业务程序的复杂性,可能协议也非常复杂。对于高并发、大流量的系统来说,每个数据包都不应该传输多余的数据(所以补齐的方式肯定不可取),LenghtFieldBasedFrameDecode更适合这样的场景。

LenghtFieldBasedFrameDecode提供了灵活的配置来支持业务消息的解码:

实际生产环境中更多是采用自定义的协议,并且编写自己的Decoder类(一般继承LenghtFieldBasedFrameDecode)来完成业务包的解码。

上一篇下一篇

猜你喜欢

热点阅读