我想大家都是在面试过程中被问到粘包和拆包怎么处理的问题,这并不是一个非常难的问题,我想大家也不用去死记硬背它,只要明白其中的道理这是一个非常简单的处理过程。而且对于tcp的粘包和拆包用netty开发只用两个api就能解决你信吗?
为了弄清这个问题我们先不考虑流控这里只看mtu(最大传输单元)。mtu我们这样理解从A到B运输货物要使用一个卡车装载运送,而这个卡车只能承载固定的货物,如果货物多了我就多运几次如果货物少我就一次拉走。
我们看一下发送网络数据的流程
sequenceDiagram
应用数据->>网络接口层: 发送数据
网络接口层->>网络: 分组发送
在Netty中我们在写网络数据的时候大多数只是调用一个writeAndFlush就可以将网络数据发送到网络上,那么对于对端接收到的数据有下面两种情况。
1、数据拆包
2、数据粘包
总结一下在同一个时间点有的数据包接收的多有的接收的少,那如果我们每次都从缓存区读进来可用数据不就出现数据一会多一会少的情况了吗?这就是粘包和拆包的问题。
那么我们如何处理粘包和拆包的问题的?
可能你不相信处理这个问题就用了Netty的两个api,我们看一下这两个api都是什么。
1、 byteBuf.markReaderIndex(); 标记当前Buffer缓冲区读指针位置
2、 byteBuf.resetReaderIndex(); 重置读指针
对于流式协议来说我们要根据协议长度判断可读缓冲区是不有足够一个协议帧的数据够我们读取,如果数据不足怎么办当然是使用byteBuf.resetReaderIndex()退回去,等缓冲区有更多的数据进来还会触发读取,我们经过反复的判断一定会有完整的数据帧,这时我们就可以正确解析数据包了。一旦读取了缓冲区内容我们的Reader index就会移动到下一个包的位置。所以只有缓冲区不足够一个帧的数据时才使用byteBuf.resetReaderIndex()回退读指针。