Netty 网络传输TCP粘包拆包

📢📢📢📣📣📣
哈喽!大家好,我是「奇点」,江湖人称 singularity。刚工作几年,想和大家一同进步🤝🤝
一位上进心十足的【Java ToB端大厂领域博主】!😜😜😜
喜欢java和python,平时比较懒,能用程序解决的坚决不手动解决😜😜😜

✨ 如果有对【java】感兴趣的【小可爱】,欢迎关注我

❤️❤️❤️感谢各位大可爱小可爱!❤️❤️❤️
————————————————

如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。

目录

1、什么是TCP粘包拆包

2、 TCP半包读写常见解决方案

        1)设置定长消息 (10字符)

        2)设置消息的边界 ($$ 切割)

        3)使用带消息头的协议,消息头存储消息开始标识及消息的  长度信息    Header+Body

3、Netty自带解决TCP半包读写方案

4、 使用解码器LineBasedFrameDecoder解决半包读写问题

5、自定义分隔符解决TCP读写问题

maxLength:

failFast:

stripDelimiter:

delimiters:

6、自定义长度半包读写器LengthFieldBasedFrameDecoder讲解



 

1、什么是TCP粘包拆包

    1)TCP拆包: 一个完整的包可能会被TCP拆分为多个包进行发送

    2)TCP粘包: 把多个小的包封装成一个大的数据包发送, client发送的若干数据包 Server接收时粘成一包

       发送方和接收方都可能出现这个原因

       发送方原因:TCP默认会使用Nagle算法

       接收方原因: TCP接收到数据放置缓存中,应用程序从缓存中读取 (上次的还没读完下次的已经到了缓存读到的数据多了)

    UDP: 是没有粘包和拆包的问题,有边界协议

2、 TCP半包读写常见解决方案

 TCP半包读写常见的解决办法

      发送方:可以关闭Nagle算法

      接受方: TCP是无界的数据流,并没有处理粘包现象的机制, 且协议本身无法避免粘包,半包读写的发生需要在应用层进行处理

      应用层解决半包读写的办法

        1)设置定长消息 (10字符)

                xdclass000  xdclass000  xdclass000  xdclass000

        2)设置消息的边界 ($$ 切割)

              sdfafwefqwefwe$$dsafadfadsfwqehidwuehfiw$$879329832r89qweew$$

        3)使用带消息头的协议,消息头存储消息开始标识及消息的  长度信息    Header+Body

3、Netty自带解决TCP半包读写方案

   Netty自带解决半包读写问题方案介绍

   DelimiterBasedFrameDecoder: 指定消息分隔符的解码器

   LineBasedFrameDecoder: 以换行符为结束标志的解码器       \\n

   FixedLengthFrameDecoder:固定长度解码器

   LengthFieldBasedFrameDecoder:message = header+body, 基于长度解码的通用解码器

TCP半包读写的问题导致服务端只拿到了一次

4、 使用解码器LineBasedFrameDecoder解决半包读写问题

     1)LineBaseFrameDecoder 以换行符为结束标志的解码器 ,构造函数里面的数字表示最长遍历的帧数

     2)StringDecoder解码器将对象转成字符串

收到的消息经过StringDecoder 之后就是string了 所以serverHandler之后的东西就不在是ByteBuf了

按入站的顺序加 Handler

out是出站的顺序

5、自定义分隔符解决TCP读写问题

显示分隔符

maxLength:

                         表示一行最大的长度,如果超过这个长度依然没有检测自定义分隔符,将会抛出TooLongFrameException

failFast:

                          如果为true,则超出maxLength后立即抛出TooLongFrameException,不进行继续解码

                          如果为false,则等到完整的消息被解码后,再抛出TooLongFrameException异常

stripDelimiter:

                         解码后的消息是否去除掉分隔符

delimiters:

                        分隔符,ByteBuf类型

6、自定义长度半包读写器LengthFieldBasedFrameDecoder讲解

官方文档:

LengthFieldBasedFrameDecoder (Netty API Reference (4.0.56.Final))

maxFrameLength      数据包的最大长度   

lengthFieldOffset      长度字段的偏移位,长度字段开始的地方,意思是跳过指定长度个字节之后的才是消息体字段

lengthFieldLength     长度字段占的字节数, 帧数据长度的字段本身的长度

lengthAdjustment

一般 Header + Body,添加到长度字段的补偿值,如果为负数,开发人员认为这个 Header的长度字段是整个消息包的长度,则Netty应该减去对应的数字(消息的长度包括header+body)

 initialBytesToStrip 从解码帧中第一次去除的字节数, 获取完一个完整的数据包之后,忽略前面的指定位数的长度字节,应用解码器拿到的就是不带长度域的数据包

    failFast 是否快速失败

简介:自定义长度半包读写器LengthFieldBasedFrameDecoder讲解

官方文档:

https://netty.io/4.0/api/io/netty/handler/codec/LengthFieldBasedFrameDecoder.html

maxFrameLength 数据包的最大长度   

lengthFieldOffset 长度字段的偏移位,长度字段开始的地方,意思是跳过指定长度个字节之后的才是消息体字段

lengthFieldLength 长度字段占的字节数, 帧数据长度的字段本身的长度

lengthAdjustment

一般 Header + Body,添加到长度字段的补偿值,如果为负数,开发人员认为这个 Header的长度字段是整个消息包的长度,则Netty应该减去对应的数字

 initialBytesToStrip 从解码帧中第一次去除的字节数, 获取完一个完整的数据包之后,忽略前面的指定位数的长度字节,应用解码器拿到的就是不带长度域的数据包

    failFast 是否快速失败

如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。               

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智达教育‍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值