我是靠谱客的博主 爱笑手套,最近开发中收集的这篇文章主要介绍C# 最简单的TCP连接添加数据帧头和校验,包括如何校验的方法。,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

mesg为需要传输的对象数据,整体结构为:帧头为最前面的2Byte,接下来的2Byte为数据长度,中间为通讯信息正文,校验为数据的最后两Byte,此处返回的是添加了数据帧头和校验的完整数据。

 //添加帧头和校验
        private byte[] GetFinallyByte(SendMessage mesg)
        {
            try
            {
                string SendMsg = JsonConvert.SerializeObject(mesg);
                byte[] byteArray = Encoding.Default.GetBytes(SendMsg);
                ushort sht = GetCrc16(byteArray);
                ushort bt = (ushort)(byteArray.Length + 2);
                byte[] numberBytes1 = BitConverter.GetBytes(sht);
                Array.Reverse(numberBytes1);
                byte[] numberBytes2 = BitConverter.GetBytes(bt);
                Array.Reverse(numberBytes2);
                byte[] string16 = new byte[] { 0xEE, 0xAA };
                byte[] FinallyByte = new byte[string16.Length + numberBytes2.Length + byteArray.Length + numberBytes1.Length];
                string16.CopyTo(FinallyByte, 0);
                numberBytes2.CopyTo(FinallyByte, string16.Length);
                byteArray.CopyTo(FinallyByte, string16.Length + numberBytes2.Length);
                numberBytes1.CopyTo(FinallyByte, string16.Length + numberBytes2.Length + byteArray.Length);
                return FinallyByte;
            }
            catch (Exception)
            {
            }
            return null;
        }

校验
计算数据帧的信息内容产生一个16位的二进制数 ,校验方法:

 private ushort GetCrc16(byte[] pData)
        {
            int fcs = 0xffff;         //  初始化
            if (pData != null)
            {
                foreach (var item in pData)
                {
                    fcs = (fcs >> 8) ^ crctab16[(fcs ^ item) & 0xff];
                }
            }
            return (ushort)~fcs;         //  取反
        }

计算方法

static const U16 crctab16[] =
{
    0X0000, 0X1189, 0X2312, 0X329B, 0X4624, 0X57AD, 0X6536, 0X74BF,
    0X8C48, 0X9DC1, 0XAF5A, 0XBED3, 0XCA6C, 0XDBE5, 0XE97E, 0XF8F7,
    0X1081, 0X0108, 0X3393, 0X221A, 0X56A5, 0X472C, 0X75B7, 0X643E,
    0X9CC9, 0X8D40, 0XBFDB, 0XAE52, 0XDAED, 0XCB64, 0XF9FF, 0XE876,
    0X2102, 0X308B, 0X0210, 0X1399, 0X6726, 0X76AF, 0X4434, 0X55BD,
    0XAD4A, 0XBCC3, 0X8E58, 0X9FD1, 0XEB6E, 0XFAE7, 0XC87C, 0XD9F5,
    0X3183, 0X200A, 0X1291, 0X0318, 0X77A7, 0X662E, 0X54B5, 0X453C,
    0XBDCB, 0XAC42, 0X9ED9, 0X8F50, 0XFBEF, 0XEA66, 0XD8FD, 0XC974,
    0X4204, 0X538D, 0X6116, 0X709F, 0X0420, 0X15A9, 0X2732, 0X36BB,
    0XCE4C, 0XDFC5, 0XED5E, 0XFCD7, 0X8868, 0X99E1, 0XAB7A, 0XBAF3,
    0X5285, 0X430C, 0X7197, 0X601E, 0X14A1, 0X0528, 0X37B3, 0X263A,
    0XDECD, 0XCF44, 0XFDDF, 0XEC56, 0X98E9, 0X8960, 0XBBFB, 0XAA72,
    0X6306, 0X728F, 0X4014, 0X519D, 0X2522, 0X34AB, 0X0630, 0X17B9,
    0XEF4E, 0XFEC7, 0XCC5C, 0XDDD5, 0XA96A, 0XB8E3, 0X8A78, 0X9BF1,
    0X7387, 0X620E, 0X5095, 0X411C, 0X35A3, 0X242A, 0X16B1, 0X0738,
    0XFFCF, 0XEE46, 0XDCDD, 0XCD54, 0XB9EB, 0XA862, 0X9AF9, 0X8B70,
    0X8408, 0X9581, 0XA71A, 0XB693, 0XC22C, 0XD3A5, 0XE13E, 0XF0B7,
    0X0840, 0X19C9, 0X2B52, 0X3ADB, 0X4E64, 0X5FED, 0X6D76, 0X7CFF,
    0X9489, 0X8500, 0XB79B, 0XA612, 0XD2AD, 0XC324, 0XF1BF, 0XE036,
    0X18C1, 0X0948, 0X3BD3, 0X2A5A, 0X5EE5, 0X4F6C, 0X7DF7, 0X6C7E,
    0XA50A, 0XB483, 0X8618, 0X9791, 0XE32E, 0XF2A7, 0XC03C, 0XD1B5,
    0X2942, 0X38CB, 0X0A50, 0X1BD9, 0X6F66, 0X7EEF, 0X4C74, 0X5DFD,
    0XB58B, 0XA402, 0X9699, 0X8710, 0XF3AF, 0XE226, 0XD0BD, 0XC134,
    0X39C3, 0X284A, 0X1AD1, 0X0B58, 0X7FE7, 0X6E6E, 0X5CF5, 0X4D7C,
    0XC60C, 0XD785, 0XE51E, 0XF497, 0X8028, 0X91A1, 0XA33A, 0XB2B3,
    0X4A44, 0X5BCD, 0X6956, 0X78DF, 0X0C60, 0X1DE9, 0X2F72, 0X3EFB,
    0XD68D, 0XC704, 0XF59F, 0XE416, 0X90A9, 0X8120, 0XB3BB, 0XA232,
    0X5AC5, 0X4B4C, 0X79D7, 0X685E, 0X1CE1, 0X0D68, 0X3FF3, 0X2E7A,
    0XE70E, 0XF687, 0XC41C, 0XD595, 0XA12A, 0XB0A3, 0X8238, 0X93B1,
    0X6B46, 0X7ACF, 0X4854, 0X59DD, 0X2D62, 0X3CEB, 0X0E70, 0X1FF9,
    0XF78F, 0XE606, 0XD49D, 0XC514, 0XB1AB, 0XA022, 0X92B9, 0X8330,
    0X7BC7, 0X6A4E, 0X58D5, 0X495C, 0X3DE3, 0X2C6A, 0X1EF1, 0X0F78,
};

校验的方法,传入接收到的数据,校验成功返回去除帧头校验的通讯信息正文:

 public string GetCrc16Str(byte[] result)
        {
            try
            {
                int ByteLength = (result[2] << 8) + result[3];
                ByteLength = ByteLength + 4;
                ushort U16 = (ushort)((result[ByteLength - 2] << 8) + result[ByteLength - 1]);
                byte[] b = new byte[ByteLength - 6];
                for (int i = 4; i < ByteLength - 2; i++)
                {
                    b[i - 4] = result[i];
                }
                // ushort res = GetCrc16(b);
                if (U16 == GetCrc16(b))
                {
                    return Encoding.UTF8.GetString(b, 0, ByteLength - 6);//把字节数组中流存储的数据以字符串方式赋值给str
                }
            }
            catch (Exception)
            {
            }
            return null;
        }

最后

以上就是爱笑手套为你收集整理的C# 最简单的TCP连接添加数据帧头和校验,包括如何校验的方法。的全部内容,希望文章能够帮你解决C# 最简单的TCP连接添加数据帧头和校验,包括如何校验的方法。所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部