C#自定义协议的封装与解析

1、 定义结构体

internal class ReceiveMsgInfo
    {
        public int Magic;
        public int Version;
        public int Length;
        public short sequence;
        public short Cmd;
        public short PayLoad_length;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
        public byte[] PayLoad;

    public ReceiveMsgInfo()
    {
        PayLoad = new byte[1024];  //再次初始化数组大小
    }
}

/// <summary>
    /// 发送文字
    /// </summary>
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public class TextMesInfo
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public byte[] From;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public byte[] To;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public byte[] Datetime;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
        public byte[] TextData;
    public TextMesInfo()
    {
        From = new byte[32];

        To = new byte[32];

        Datetime = new byte[32];

        TextData = new byte[512];
    }
}

对于byte[]类型数据,要定义其元素数量(即字节数),创建结构体时要创建其大小,以便后面copyTo函数使用。

2、 封装
2.1 将payload结构体封装为byte[]

IntPtr paramPtr = Marshal.AllocHGlobal(Marshal.Sizeof(typeof(payload结构体类));
//定义一个payload结构体大小的内存空间(非委托)

2.2将结构体转换为非委托指针空间

Marshal.StructureToPtr(payload结构体类, paramPtr,true);

2.3将非委托指针空间存到byte[]

Marshal.Copy();

备注:
1、 结构体新建时必须声明其大小(对于byte[]类型而言,int类型本身已有指定);
2、 将值赋到结构体byte[]时,采用Array.CopyTo(); 这样的话结构体长度不会变;
3、 用完后记得释放分配内存空间,因为是非委托模式

Marshal.FreeHGlobal(IntPtr名称);

3、 解析


版权声明:本文为qq_43053398原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。