串口数据解析递归与非递归的写法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了串口数据解析递归与非递归的写法相关的知识,希望对你有一定的参考价值。

暂时没有弄明白为什么递归的写法会影响到通讯速度,做一个记录方便以后查阅以及解决吧.


    /// <summary>
    /// 解析数据-递归方式
    /// </summary>
    private void ParseRecursive(List<byte> buffer)
    {
        // 从缓冲中查找帧头一直找到为止
        // 丢弃缓冲前部没有与帧头匹配成功的字节
        while (buffer.Count > 0)
        {
            if (buffer[0] != DEF_HEADER)
            {
                buffer.RemoveAt(0);
            }
            else break;
        }

        // 一个完整数据包至少10个字节
        if (buffer.Count < 10) return;

        // 验证串号
        ushort sn = BitConverter.ToUInt16(buffer.ToArray(), 1);
        if (sn != DEF_SERIAL)
        {
            buffer.RemoveAt(0);
            ParseRecursive(buffer);
            return;
        }

        // 验证长度
        // 无效的长度值
        if (buffer[3] < 1)
        {
            buffer.RemoveAt(0);
            ParseRecursive(buffer);
            return;
        }

        // 验证长度校验
        byte len = buffer[3];
        if (buffer[4] != (byte)~len)
        {
            buffer.RemoveAt(0);
            ParseRecursive(buffer);
            return;
        }

        // 验证帧尾
        if (buffer[len + 8] != DEF_FRAMEND)
        {
            buffer.RemoveAt(0);
            ParseRecursive(buffer);
            return;
        }

        // 验证校验位
        byte bcc = buffer[len + 7];
        byte vbcc = buffer[5];
        for (int i = 6; i < len + 2; i++) vbcc ^= buffer[i];
        if (bcc != vbcc)
        {
            buffer.RemoveAt(0);
            ParseRecursive(buffer);
            return;
        }

        // 数据解析
        byte[] data = new byte[len];
        buffer.CopyTo(5, data, 0, len);
        buffer.RemoveRange(0, len + 9);

        // 处理数据
        Process(data);
    }

    /// <summary>
    /// 解析数据-非递归方式
    /// </summary>
    private void ParseNotRecursive(List<byte> buffer)
    {
        while (buffer.Count > 0)
        {
            // 查找帧头
            if (buffer[0] != DEF_HEADER)
            {
                buffer.RemoveAt(0);
                continue;
            }

            // 一个完整数据包至少10个字节
            if (buffer.Count < 10) return;

            // 验证串号
            ushort sn = BitConverter.ToUInt16(buffer.ToArray(), 1);
            if (sn != DEF_SERIAL)
            {
                buffer.RemoveAt(0);
                continue;
            }

            // 验证长度      
            byte len = buffer[3];
            if (len < 1)                // 长度值无效
            {
                buffer.RemoveAt(0);
                continue;
            }
            if (buffer[4] != (byte)~len)
            {
                buffer.RemoveAt(0);
                continue;
            }

            // 验证帧尾
            if (buffer[len + 8] != DEF_FRAMEND)
            {
                buffer.RemoveAt(0);
                continue;
            }

            // 验证校验位
            byte bcc = buffer[len + 7];
            byte vbcc = buffer[5];
            for (int i = 6; i < len + 2; i++) vbcc ^= buffer[i];
            if (bcc != vbcc)
            {
                buffer.RemoveAt(0);
                continue;
            }

            // 解析数据包完成
            byte[] data = new byte[len];
            buffer.CopyTo(5, data, 0, len);
            buffer.RemoveRange(0, len + 9);

            // 处理数据
            Process(data);
        }
    }

 

以上是关于串口数据解析递归与非递归的写法的主要内容,如果未能解决你的问题,请参考以下文章

递归算法之阶乘代码实现与非递归实现

二分查找算法(递归与非递归两种方式)

数据结构与算法二叉树递归与非递归遍历(附完整源码)(转)

C++实现二叉树 前中后序遍历(递归与非递归)非递归实现过程最简洁版本

递归与非递归的转换

快速排序:递归与非递归