BytesIO | C# 优雅处理通信中的粘包和断包(二)—— 处理非固定长度的协议(完整源码+视频教程)

本文介绍了如何优雅地处理C#中非固定长度的通信协议,通过分析包含头部、长度字段、数据和校验位的协议格式,详细讲解了如何编写解包器来正确解析粘包和断包问题。作者提供了一个具体的协议实例,并展示了相应的代码实现,帮助理解如何动态计算包长度并进行数据校验。

C# 优雅处理通信中的粘包和断包(二) 处理非固定长度的协议

在这里插入图片描述


前言

上篇文章中我们讲了一下固定长度的协议该怎么样使用解包器去解析,那今天我们再补充一点,就是非固定程度的协议该怎么样使用解包器去解析


分析协议格式

我这里设计了一个协议,它长成这个样子:
在这里插入图片描述
我们来一起分析一下这个协议,协议头部这里设计的是a a b b。
第二部分是长度,也就是说到这一位往后还要接收多长的数据。
然后看数据长度占一个字节,假如数据位长度标记为n时,数据部分里有多少字节的数据呢?如果我们的这个长度里面的值是n的话,那数据位的长度就是n减1,最后一位是校验校验位占一个字节。

我们看第一个实例,AABB为起始头部。然后长度位里面标记着是7,也就是说从这一位往后,我还要接收7个字节的数据。
最后一位是我们的校验位,校验位校验的是从AABB起始位之后校验位之前的这一段数据;
下一个例子也是一样的,数据内如加校验位一共是4个字节,校验和计算的是从AABB起始位之后校验位之前这段数据的Checksum.


视频教程

【女朋友都能学会】C# 协议解包器(优雅处理粘包断包)


源代码

让我们来看一下代码该怎么实现它。

在上一篇文章《解包器的基础用法》中实现的解包器它的协议是固定的八位长度,所以在计算包长度的时候就给了一个默认的八位,实现起来非常的简单。

我们今天再实现一个,按照上方这个协议去实现一个与之匹配的解包器。

    /// <summary>
    /// 非固定长度的协议解包器
    /// 数据包长度存放于数据包内指定位
    /// </summary>
    public class SimpleData2Unpacker : Unpacker
    {
        public SimpleData2Unpacker()
        {
            StartMark = new byte[] { 0xAA, 0xBB };
        }

        protected override int CalculatePacketLength(IEnumerable<byte> bytes)
        {
            if (bytes.Count() < 3)
            {
                return 0;
            }
            else
            {
                return bytes.ElementAt(2) + 3;
            }
        }
    }

我们需要重写这个计算包长度的方法,之前是固定的长度是个固定长度是八,我们现在是根据协议来计算它的长度的,就要重写一下这个方法。
我们至少需要知道几位才可以确定整个包的长度呢?至少要到第三位长度位才行。我们知道这位之后才知道它后面的内容有多长。
所以在计算包长度这个地方,如果无法判断总包长度的话可返回零。
如果断包它发生在数据长度位之前,比如只收到了两位数据,也就是AABB,那这个时候我们是没有办法判断整个包长度的,只有数据包的长度超过了这个第三位,那就可以知道这个数据包有多长。
因此编写判断条件的逻辑是:如果我拿到的这个数据的长度,它如果小于三的话呢,那我们就返回一个零就好,否则我们就要去找出这段数据里的第三位。
另外由于索引从零开始数的第三位,因此应该再加上前面的三位,那这样的话那我们就计算出来整个包的长度了,这就是非固定长度协议的解包器的配置方法


相关文章

C# 优雅处理通信中的粘包和断包(一) 处理固定长的的协议
C# 优雅处理通信中的粘包和断包(二) 处理非固定长度的协议
C# 优雅处理通信中的粘包和断包(三) 处理使用结束符的协议

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

猿长大人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值