TCP的粘包,拆包及解决方法介绍

一、关于协议

在我们日常生活中,或者说日常工作中会有很多的协议。大家可能都知道有协议但协议到底是什么大家可能不太清楚,那么下面我们来说一下什么是协议,以及一些常见的协议。

我们首先来说一下常见的协议:

  • tcp协议

    TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 基于IP的传输层协议。
  • UDP协议

    UDP(User Datagram Protocol)传输与IP传输非常类似。你可以将UDP协议看作IP协议暴露在传输层的一个接口。
  • http协议

    HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

好我们就说简单介绍了一下,上面三个协议。多的也就不说了、下去我们大家可以去自行了解一下。因为要详细讲解的话,也许需要一本书的的文字量,更何况我也不一定讲的明白。

那么我们下面在说说什么是协议:

协议,其实你大家都把它想复杂了。用通俗的话来讲协议就是一个规定而已。那为啥要有这个规定呢,也就是这个协议呢?当然是有好处的,是为了更好的解决一系列的问题,以及更规范。这个就像我们去买烟或者买手机一样。规定是什么呢,规定就是你要给相对应的钱,才能给你对应的烟。是一个意思你不给钱或给少了那么你就拿不到你想要的东西这个就是规定这也就是协议。和能举的例子不够明确吧,大家尽量理解:协议就是实现约定好的一个规定,如果你不按照规定玩,那么你肯定得不到想要的东西,换句话说就是不带你玩了。

二、tcp的粘包以及解决方案

这里开始进入我们今天的重点!

在我我们使用tcp协议啊还是http协议也好,其实我们都是面向网络编程的。且在我们编程的时候其实无非就是前端把数据发给后端,后端把数据发给前端。

在我们java中呢,做nio网络开发时又是面向流,或者说面向管道开发。这个怎么解释呢?就是数据传输了。我们的客户端要给服务端发数据,服务端也要发数据给客户端。而且在我们java中tcp协议的数据传输,在低层其实都是先把数据分端打包,然后在以低层网络流的形式传输出去。什么是流呢?流其实我们可以想象是在客户端和服务端之间有两个管子,我们服务端与客户端的通信就靠这个两个管道来完成。流就是在管道中流动的数据。

好了那么问题来了。我们tcp连接建立好了,开始发送数据的时候这个流就开始流动了,那么当我们发一个很大的数据包时紧接着一个小数据包,这个时候通常会造成粘包现象。其实这个大家想一下就会明白一定会有这样的问题,因为你用的是流,另一端是不知道你这个数据包什么时候传输完成的。下面看一下图:



TCP的粘包,拆包及解决方法介绍_第1张图片




当我们发生第二种请情况的时候就出现了粘包现象。这就是因为流的问题,且另一端不知道上一个数据包合适结束,这样就会到致我们数据在解析的时候出现问题。当然出现拆包和粘包的情况还是有不少的,我们就不一一列举,大家知道是怎么回事就好了。下面我们来说一下怎样解决这个问题。

解决办法:

  1. 如果我们使用Netty的话可以使用Netty的常用编解码器
    LineBasedFrameDecoder (换行)
    DelimiterBasedFrameDecoder(添加特殊分隔符报文来分包)
    FixedLengthFrameDecoder(使用定长的报文来分包)
    LengthFieldBasedFrameDecoder (自定义解码器跟编码器)
  2. 我们可以进行自定协议,添加消息的首部长度啊等信息
  3. 固定数据长度

好我们今天就到这个里,下次我们将讲解,Netty的常用解码器,以及自定义协议的使用。

你可能感兴趣的:(netty)