C#通信,结构体和byte数组互转

在C#进行UDP或者TCP/IP通信时,经常要用到byte数组来传递信息。一开始,我是使用BitConverter和Encoding来进行转换。后来经过大神指导,其实一切不必那么麻烦。只需将要发送的信息封装成结构体,使用C#自带的一个转换类便可轻松搞定。

首先建立一个结构体

//必须引用的库
using System.Runtime.InteropServices;

namespace Test
{
    [StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi,Pack=1)]
    struct SensorHeadInfo
    {
        public uint cmdId;
        [MarshalAs(UnmanagedType.ByValArray,SizeConst=5)]
        public byte[] time_t;
        public ushort msgLength;
        public byte errorFlag;
        public byte moduleId;
    }
}

其次建立转换类

using System;
using System.Runtime.InteropServices;

namespace Test
{
    class MessageSwitch
    {
        /// <summary>
        /// 将结构体转换为byte数组
        /// </summary>
        /// <typeparam name="T"> 泛型T</typeparam>
        /// <param name="structObj">结构体对象</param>
        /// <returns></returns>
        public static byte[] StructToBytes<T>(T structObj) where T : struct
        {
            // 获取结构体对象的字节数
            int size = Marshal.SizeOf(structObj);
            byte[] bytes = new byte[size];
            // 申请内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体内容拷贝到上一步申请的内存空间
            Marshal.StructureToPtr(structObj, structPtr, false);
            // 将数据拷贝到byte数组
            Marshal.Copy(structPtr, bytes, 0, size);
            // 释放申请的内存
            Marshal.FreeHGlobal(structPtr);

            return bytes;
        }

        public static T BytesToStruct<T>(byte[] bytes) where T:struct
        {
            T obj = new T();

            int size = Marshal.SizeOf(obj);

            // 如果结构体对象的字节数大于所给byte数组的长度,则返回空
            if (size > bytes.Length)
            {
                return (default(T));
            }

            IntPtr structPtr = Marshal.AllocHGlobal(size);
            Marshal.Copy(bytes, 0, structPtr, size);
            object tempObj = Marshal.PtrToStructure(structPtr, obj.GetType());
            Marshal.FreeHGlobal(structPtr);

            return (T)tempObj; 
        }
    }
}
使用方法如下

 public static byte[] getSensorHeaserInfo()
        {
            Random random = new Random(DateTime.Now.Millisecond + DateTime.Now.Second);
            SensorHeadInfo headerInfo = new SensorHeadInfo();

            int index = random.Next(0, moduleTypeVal.Count);

            headerInfo.cmdId = 12;
            headerInfo.time_t = new byte[5];
            headerInfo.moduleId = 13;

            // get message length
            headerInfo.msgLength = (ushort)13;
            // create message bytes array
            byte[] res = new byte[13];
 <span style="white-space:pre">	</span>    MessageSwitch.StructToBytes<SensorHeadInfo>(headerInfo).CopyTo(res, 0);

            return res;
        }
至于字节数转换结构体则如下

byte[] msg = m_listenUdp.Receive(ref remoteEndPoint);
SensorHeadInfo headerInfo = MessageSwitch.BytesToStruct<SensorHeadInfo>(msg);
接收到消息后直接转换



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值