在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);
接收到消息后直接转换