前言:
前两天在知乎上看了很多关于TCP的内容,这里说TCP粘包其实是很不靠谱的,TCP只是一个传输流的协议或者说介质,传输字节流,而包这个概念和流还是不一样的,所以粘包和TCP其实并无关联,但是呢? 这类问题问太多了,假的也快变成真的了,不过真正的原理自己知道就好,关于问题的记录还是用这种“通俗易懂”的方式来记录; 关于这块其实自己在项目里实现过了,所以并不算太大的问题~
更详细的可以去知乎搜 TCP粘包问题,保证有收获~
1.粘包的原因
**优化算法(nagle算法):**将多次间隔较小且数据量小的数据,合并成一个大的数据包,然后封包,虽然提高了效率,但是接收端就难以分辨出完整的数据包了
有几种情况,分别读取了两个数据包,还有一种是粘在一起了, 还有一种是完整的一个以及另外一个包的部分内容,第二次读取到剩余的内容;
TCP没有消息边界保护,有可能拆包 有可能粘包,服务器端不知道该读取多少,就会出现问题
2.如何解决粘包问题
解决粘包拆包问题,就是自定义一个协议,协议里面包括发送的长度和内容,发送过去以后,服务器端首先读取里面的长度,然后定义一个该长度大小的byteBuf 然后读入进去就可以了!
核心问题是解决每次读取数据长度的问题 自定义协议+编解码器
为什么要加 编解码器呢? 在编解码器里面 就处理好了,把编码器处理的 字符长度拿出来,然后在这里把 协议定义好的长度 ,这里的长度是从发送过来的包读取的,然后解码以后,按照确定好的长度放到一个list里面,让后面的handler来处理;
把协议包对象发送过去,(里面有长度和内容),然后用编解码器处理; 接收的时候也是用 协议包对象去封装读取!普通的tcp是没有这种处理的,直接放到handler里面了(这里指在netty里的实现)