zoukankan      html  css  js  c++  java
  • netty学习笔记一:TCP粘包拆包

    什么是TCP拆包粘包

    假设客户端发送了2条消息M1,M2。可能会出现以下几种情况。

    1、服务端正常接收到M1,M2这两条消息。

    2、服务端一次接收到了2个数据包,M1和M2粘合在一起,这时候就被称为TCP粘包。

    3、服务端分两次读取到了两个数据包,第一次读取到M1包整包和M2包部分内容M2_1,第二次读取到了M2剩余的内容M2_2,这时候被称为TCP拆包。

    4、服务端分两次读取到了两个数据包,第一次读取到M1包的部分内容M1_1,第二次读取到了M1剩余的内容M1_2和M2整包,这时候也是发生了TCP拆包。

    5、当服务端TCP接收滑窗非常小,或者M1、M2数据包比较大时,服务端需要将M1,M2进行多次拆包才能接收完全,这时候也是发生了TCP拆包。

    同时,我们需要明确的是,其实在TCP层面上它是没有拆包粘包概念的。因为TCP只是负责传输上层协议所提供的数据,它本身并不知道这些数据的关系,只是像流一样将这些数据传输过去。因此,这个拆包粘包概念更准确来说是相对于应用层数据划分的。

    拆包粘包产生原因

    粘包可能的产生原因

      1、原本没有粘包进行TCP传输的数据包,在read操作调用不及时去读取缓冲区数据的情况下,很可能会发生粘包;

      2、应用程序写入数据大小小于缓冲区大小,网卡会将应用多次写入的数据发送到网络上,这将会发生粘包。

    拆包可能的产生原因

    1、应用程序写入的数据比缓冲区还大时,数据不能一次性发送,将发生拆包。

    2、TCP进行分段时数据大小大于MSS大小的时候将发生拆包。

    3、以太网帧的payload数据大于MTU大小时发生拆包。

     

    注:MTU和MSS的概念如下。

    MTU:代表TCP/IP协议传输数据报时的最大传输单元。以太网协议规定最大帧长度是1500Byte(不包括报文头部)。

    MSS: MSS是TCP专属概念,TCP在三次握手建立连接过程中,会在SYN报文中使用MSS(Maximum Segment Size)选项功能,协商交互双方能够接收的最大段长MSS值。其标识TCP能够承载的最大的应用数据段长度。

    MSS=MTU-20字节TCP报头-20字节IP报头。在IPv4网络中,一般情况下,MSS=1460=1500-20-20。 在IPv6网络中,一般情况下,MSS=1440=1500-20-40。

     常见解决策略

    1、消息定长。例如每个报文的大小固定为200字节,不够则空格补齐;

    2、在包尾增加回车换行符进行分割,如FTP协议;

    3、将消息分成消息头和消息体,消息头中包含表示消息()总长度的字段。如下示例,length字段代表本条消息的长度大小。

     +————+—————————+ 

      | Length   | Actual Content          |

      | 0x000C  | "HELLO, WORLD"   |

     +————+—————+———-+ 

     Netty常见解决类

    1、LineBasedFrameDecoder:基于行来进行消息粘包拆包处理的。

    2、DelimiterBaseFrameDecoder:基于分隔符做结束标志进行粘包拆包处理的,对于使用" "," "做分隔符内部会调用LineBasedFrameDecoder来做统一的行分割。

    3、FixedLengthFrameDecoder:基于固定长度消息进行粘包拆包处理的。

    4、LengthFieldBasedFrameDecoder:基于消息头指定消息长度进行粘包拆包处理的。

  • 相关阅读:
    Linux----------系统管理之释放内存
    阿里云OSS挂载到ECS(注意fuse版本,必须和源码对应)
    数据库图形化管理工具navicat
    linux集群管理工具clustershell
    记一次nginx启动报错
    虚拟化之KVM
    虚拟化之-XEN(未完待续)
    虚拟化
    Linux----------Jenkins基础
    Linux日常系统管理命令
  • 原文地址:https://www.cnblogs.com/magotzis/p/9527024.html
Copyright © 2011-2022 走看看