面试题:聊聊TCP的粘包、拆包以及解决方案

简介: 面试题:聊聊TCP的粘包、拆包以及解决方案

TCP的粘包和拆包问题往往出现在基于TCP协议的通讯中,比如RPC框架、Netty等。如果你的简历中写了类似的技术或者你所面试的公司使用了相关的技术,被问到该面试的几率会非常高。


今天这篇文章就带大家详细了解一下TCP的粘包和拆包以及解决方案。


什么是粘包?

在学习粘包之前,先纠正一下读音,很多视频教程中将“粘”读作“nián”。经过调研,个人更倾向于读“zhān bāo”。


如果在百度百科上搜索“粘包”,对应的读音便是“zhān bāo”,语义解释为:网络技术术语。指TCP协议中,发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。


TCP是面向字节流的协议,就是没有界限的一串数据,本没有“包”的概念,“粘包”和“拆包”一说是为了有助于形象地理解这两种现象。


为什么UDP没有粘包?

粘包拆包问题在数据链路层、网络层以及传输层都有可能发生。日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生粘包拆包问题,因此粘包拆包问题只发生在TCP协议中。


粘包拆包发生场景

因为TCP是面向流,没有边界,而操作系统在发送TCP数据时,会通过缓冲区来进行优化,例如缓冲区为1024个字节大小。


如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题。


如果一次请求发送的数据量比较大,超过了缓冲区大小,TCP就会将其拆分为多次发送,这就是拆包。


关于粘包和拆包可以参考下图的几种情况:


image.png上图中演示了以下几种情况:


正常的理想情况,两个包恰好满足TCP缓冲区的大小或达到TCP等待时长,分别发送两个包;

粘包:两个包较小,间隔时间短,发生粘包,合并成一个包发送;

拆包:一个包过大,超过缓存区大小,拆分成两个或多个包发送;

拆包和粘包:Packet1过大,进行了拆包处理,而拆出去的一部分又与Packet2进行粘包处理。

常见的解决方案

对于粘包和拆包问题,常见的解决方案有四种:


发送端将每个包都封装成固定的长度,比如100字节大小。如果不足100字节可通过补0或空等进行填充到指定长度;

发送端在每个包的末尾使用固定的分隔符,例如\r\n。如果发生拆包需等待多个包发送过来之后再找到其中的\r\n进行合并;例如,FTP协议;

将消息分为头部和消息体,头部中保存整个消息的长度,只有读取到足够长度的消息之后才算是读到了一个完整的消息;

通过自定义协议进行粘包和拆包的处理。

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

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


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

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

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

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

基于Netty进行网络读写的程序,可以直接使用这些Decoder来完成数据包的解码。对于高并发、大流量的系统来说,每个数据包都不应该传输多余的数据(所以补齐的方式不可取),LenghtFieldBasedFrameDecode更适合这样的场景。


小结

TCP协议粘包拆包问题是因为TCP协议数据传输是基于字节流的,它不包含消息、数据包等概念,需要应用层协议自己设计消息的边界,即消息帧(Message Framing)。如果应用层协议没有使用基于长度或者基于终结符息边界等方式进行处理,则会导致多个消息的粘包和拆包。


虽然很多框架中都有现成的解决方案,比如Netty,但底层的原理我们还是要清楚的,而且还要知道有这么会事,才能更好的结合场景进行使用。



目录
相关文章
|
移动开发 网络协议 Java
TCP 粘包/拆包问题
《基础系列》
129 0
TCP 粘包/拆包问题
|
移动开发 网络协议
TCP的粘包拆包问题+解决方案
TCP的粘包拆包问题+解决方案
124 0
TCP的粘包拆包问题+解决方案
|
网络协议
TCP的粘包和拆包
TCP的粘包和拆包
140 0
|
移动开发 网络协议 IDE
Netty通信遇到了TCP拆包粘包问题?看这篇文章如何解决
在上一篇文章中主要是使用Springboot开发了一个Netty通信的基本案例,这篇文章是在上一篇文章的基础之上进行讲解的,主要是考虑传输数据如果遇到粘包问题该如何解决。 这篇文章会按照一下步骤进行讲解,希望对你有所收获: 1、什么是TCP粘包拆包 2、Netty中粘包问题的问题重现 3、Netty中粘包问题的解决方案 OK,在你心中有这么一个基本的脉络之后就可以开始今天的文章了。本系列所有的文章都会给出完整的代码,且在电脑上真实运行了一遍,确保无误。
228 0
Netty通信遇到了TCP拆包粘包问题?看这篇文章如何解决
|
移动开发 网络协议 Java
牛逼!TCP 粘拆包问题及 Netty 中的解决方案
本文选自 Doocs 开源社区旗下“源码猎人”项目,作者 AmyliaY。
224 0
牛逼!TCP 粘拆包问题及 Netty 中的解决方案
|
移动开发 网络协议
【Netty】TCP粘包和拆包
前面已经基本上讲解完了Netty的主要内容,现在来学习Netty中的一些可能存在的问题,如TCP粘包和拆包。
121 0
【Netty】TCP粘包和拆包
|
JSON 网络协议 数据格式
TCP 粘包/拆包的原因及解决方法?
TCP粘包、拆包属于网络底层问题,在数据链路层、网络层、传输层都有可能出现。日常的网络应用开发大多数在传输层出现,而UDP是由消息保护边界的,不会发生粘包、拆包问题,只发生在TCP协议中。假设客户端向服务端发送了两个连续的数据包Packet1、Packet2;
695 0
TCP 粘包/拆包的原因及解决方法?
|
移动开发 缓存 网络协议
面试题:聊聊TCP的粘包、拆包以及解决方案
面试题:聊聊TCP的粘包、拆包以及解决方案
189 0
面试题:聊聊TCP的粘包、拆包以及解决方案
|
移动开发 网络协议
Netty解决TCP粘包/拆包的问题
首先要明确, 粘包问题中的 “包”, 是指应用层的数据包.在TCP的协议头中, 没有如同UDP一样的 “报文长度” 字段,但是有一个序号字段.
Netty解决TCP粘包/拆包的问题
|
网络协议 前端开发 Java
tcp的粘包和拆包示例以及使用LengthFieldFrameDecoder来解决的方法
粘包和拆包是什么?TCP协议是一种字节流协议,没有记录边界,我们在接收消息的时候,不能人为接收到的数据包就是一个整包消息 当客户端向服务器端发送多个消息数据的时候,TCP协议可能将多个消息数据合并成一个数据包进行发送,这就是粘包 当客户端向服务器端发送的消息过大的时候,tcp协议可能将一个数据包拆...
1036 0