TCP黏包半包解析

前置知识:在网络模型的传输层中,常用的有TCP/UDP两种传输协议,相比于UDP协议来说,TCP协议是一个可靠的传输协议,并且是一个面向数据流的协议;所谓面向数据流,其实是指数据传输是以流式的方式传输,这些传输的数据就像一条河里的水,他们之间是没有缝隙的,也就是说TCP协议传输的数据是无边界的。而UDP是面向数据包的,收发数据包要么全收要么不收,数据包与数据包之间是有明显的边界的。

一、粘包、半包原因分析

1.1 粘包

        TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,应用程序从缓冲区中取数据是整个缓冲区中有多少取多少。造成黏包的原因:

        发送方:TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量),TCP在发送时TCP会默认加上40字节的报文头,假设发送的消息长度较短,会造成资源浪费,且报文段数量过多,Nagle算法会自动将消息长度较短的消息合并成一个报文,就会造成粘包现象;

        接收方:接收方缓冲区较大,在未能及时读取消息的情况下,下一个消息也发送过来了,就会造成粘包现象。

1.2 半包

        TCP半包是指发送方发送的一包数据到接收方接收时拆分成多包。造成半包的原因:

        发送方:发送方缓冲区较小,应用程序写入数据的字节大小大于套接字发送缓冲区的大小;

        接收方

  • 进行MSS大小的TCP分段。MSS是最大报文段长度的缩写。MSS是TCP报文段中的数据字段的最大长度。数据字段加上TCP首部才等于整个的TCP报文段。所以MSS并不是TCP报文段的最大长度,而是:MSS=TCP报文段长度-TCP首部长度
  • 以太网的payload大于MTU进行IP分片。MTU指:一种通信协议的某一层上面所能通过的最大数据包大小。如果IP层有一个数据包要传,而且数据的长度比链路层的MTU大,那么IP层就会进行分片,把数据包分成托干片,让每一片都不超过MTU。注意,IP分片可以发生在原始发送端主机上,也可以发生在中间路由器上。

二、解决办法

        由于底层的TCP发送的数据是无边界的,所以在底层是无法保证数据包不被拆分和重组的,通过上层的应用协议栈设计来解决,在netty中提供了多种解决方案。

2.1 FixedLengthFrameDecoder

        FixedLengthFrameDecoder也就是消息定长解码器,消息定长是指例如每个报文的大小为固定长度200字节,如果不够,空位补空格。

2.2 LineBasedFrameDecoder & DelimiterBasedFrameDecoder

        分隔符解码器,通过在包尾增加分割符,在解析时根据分隔符来进行拆分消息,但若是某条消息超过给定的消息长度,则抛出异常;

2.3 LengthFieldBasedFrameDecoder

        加入消息头字段,用于表示整个消息的长度,通常设计思路为消息头的第一个字段使用int32来表示消息的总长度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值