|
|
51CTO旗下网站
|
|
移步端
  • 采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    咱们采用TCP协和在传输数据的时节,如果数据块比较大,就会考虑将他切分。把一个大的数据包进行切割成一个个小的数据包发送。此刻就会遇到拆包和粘包的题材。

    笔者:Java的架构师技术栈 来源:当日第一| 2020-01-06 15:23

     

    这篇文章会按照以下步骤进行讲解,瞩望对你有所收获:

    1、什么是TCP粘包拆包2、Netty官方粘包问题的题材重现3、Netty官方粘包问题的解决方案

    OK,在你心中有这么一个主导的系统之后就足以开始今天的篇章了。资本系列所有的篇章都会给出一体化的编码,且在计算机上真正运行了一遍,确保无误。

    一、什么是TCP拆包和粘包

    咱们采用TCP协和在传输数据的时节,如果数据块比较大,就会考虑将他切分。把一个大的数据包进行切割成一个个小的数据包发送。此刻就会遇到拆包和粘包的题材。

    比如说在此间客户端发送了两个数据包D1和D2到劳动端,在传输的时节就可能会遇到下列问题:

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    穿过上面这张图相信你基本上能够理解了。不过我们在此间还是要求稍微解释一下:

    气象1:D1和D2正常发送,每次发送一个整包。

    气象2:D1数据包比较大,D2比起小。着重次发送D1的组成部分,其次次发送D1剩下的和D2整包。这叫拆包。

    气象2:D1和D2数据包都比较小,一次发送两个整包,这就叫做粘包。

    气象4:D1数据包比较小,D2比起大。着重次发送D1整包和D2一些,其次次发送D2剩下的。这叫拆包。

    气象5:D1和D2数据包都比较大,此刻分开发。

    为什么会出现这样的题材呢?想要解释清楚,就不能不要考虑到计算机网络的相关知识了,TCP在接到数据的时节,有一度滑动窗口来支配接受数据的大小,其一滑动窗口你就足以了解为一个缓冲区的大小。引黄灌区满了就会把数据发送。数据包的大小是不一定的,有时候比缓冲区大,有时候小。此刻就会出现上面的场面。

    下我们采用代码来重现这个场面。

    二、题材重现

    1、前提准备

    咱们是基于Springboot付出的,故此还是和上一节一样,第一创建一个Springboot的web水利,补充一下依赖:

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    如果你没有使用maven,载入相关jar包,直接导入IDE官方即可。

    2、劳务端代码开发

    步骤一:创造server类

    其一server类,在上一篇文章中提出,是一番模板类,直接拿来用即可。

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    在地方的这个代码中同样我们着重的是关心ServerUAVHandler的贯彻。

    步骤二:Handler的贯彻

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    在这个类中,采用channelRead办法来读取客户端发送过来的消息。

    (1)第一定义了一番counter,用于计算客户端发送了若干条信息。

    (2)在channelRead其间,第一将msg转折为ByteBuf。

    (3)名将buf的多寡转化为字节byte

    (4)名将buf的字节数据转化为String品种,下一场输出。

    (5)采用ctx的writeAndFlush办法,每收到一个客户端的多寡,送对方回答一个A。别忘了还有一个换行符。

    在地方的这个代码中,重大的就是劳动端每收到一枝客户端的消息,就送人家回复一枝。具体地说客户端和劳务端的信息数量应该是一样的。

    3、客户端代码开发

    步骤一:创造client类

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    同样的编码的逻辑在上一篇文章中已经说了,咱们还是最关心的风波处理类Handler。

    步骤二:Handler贯彻

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    其一客户端的Handler看上去有点多,一起有两个办法,channelActive和channelRead。

    (1)channelActive其中使用for循环给服务器发送了100条,我爱你。每次发送还有在最后添加一个换行符。

    (2)channelRead其中接受服务器返回的信息。

    按道理来讲,客户端给服务端发送了100条数据,这就是说服务端也会回来回来100条。咱们来检查一下。

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    此地输出的是劳动端的消息,副上面的进出口结果你就会发现,其实客户端的“我爱你”都把黏在了一块。原有100条但是现在却只有17条了,这就是发生了粘包现象。

    如何来解决呢?下我们看看。

    三、粘包问题解决

    消灭之笔触很简单,也就是每次发送一个数据包的时节,补充一个标识符,读的时节一直读到这个标识符才表示一下完整的数据包。在地方我们添加的是line.separator,也就是换行符“\n”。

    1、劳务端server类更改。

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    2、劳务端Handler类更改

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    3、客户端Client改变

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    4、客户端Handler改变

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    客户端和劳务端改的中央都一样,不过还是贴了出去,如今我们再运行一泰国。

    采用Netty打电话时,赶上TCP粘包拆包问题如何解决?答案如此简单

    观看没是不是很神奇。咱们来分析一下我们都修改了什么。

    好像我们就是否在server和client类添加了两个类,一度是LineBasedFrameDecoder,一度是StringDecoder,其它的都是直接删除,这两个类有什么打算呢?

    (1)LineBasedFrameDecoder的企图是在读取数据的时节,一直读到是否含有换行符“\n”或者是“\r\n”。如果读到了就表示该结束了。故此就拿到了这一行的数据包。

    (2)StringDecoder用于对之前LineBasedFrameDecoder读取的这一行数据包进行解码。名将对象转换为字符串。

    OK,好像他们俩搭配,工作真不累,如今我们终于得以解决粘包的题材了,但是同时也出现了一番新的问题,那就是如果我们的标识符不是换行符“\n”或者是“\r\n”又该怎么办呢?幸好Netty同样为我们提供了几种其他的解码器,叫做DelimiterBasedFrameDecoder和FixedLengthFrameDecoder,眼前这个可以自行完成以分隔符做结束标志的信息,后面这个可以自行完成对定长消息的解码。都得以解决粘包拆包问题。

    【编纂推荐】

    1. 如何用Python贯彻TCP的过渡与通信?
    2. IP、UDP和TCP的关联
    3. 3000字讲讲TCP协和,拉手挥手不是你想的那么简单
    4. 图集:TCP/IP协和集和安全
    5. 4000字详解TCP逾期与重传,看完没收获算我输
    【义务编辑: 武晓燕 TEL:(010)68476606】

    点赞 0
  • Netty  TCP  粘包
  • 分享:
    大家都在看
    猜你喜欢
  • 订阅专栏+更多

    Python使用场景实战手册

    Python使用场景实战手册

    Python使用场景实战手册
    共3章 | KaliArch

    0人口订阅学习

    一步到位玩儿透Ansible

    一步到位玩儿透Ansible

    Ansible
    共17章 | 骏马金龙1

    99人口订阅学习

    云架构师修炼手册

    云架构师修炼手册

    云架构师之必不可少技能
    共3章 | Allen在路上

    106人口订阅学习

    读 书 +更多

    鸟哥的Linux私房菜 基础学习篇(其次版)

    该书全面而详细地介绍了Linux操作系统。全党分为5个组成部分:先后部分着重说明Linux的滥觞及力量,如何规划和设置Linux长机;其次部分介绍Linu...

    订阅51CTO邮刊

    点击这里查看样刊

    订阅51CTO邮刊

    51CTO劳务号

    51CTO官微

    1.