在实现基于UDP的协议时,我试图使用结构来解析套接字数据。 我搜索了,我可以使用这两个函数在byte []和struct:
之间进行转换 byte[] StructToBytes(object structObj)
{
int size = Marshal.SizeOf(structObj);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(structObj, buffer, false);
byte[] bytes = new byte[size];
Marshal.Copy(buffer, bytes, 0, size);
return bytes;
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
static object BytesToStruct(byte[] bytes, Type strcutType, int offset = 0)
{
int size = Marshal.SizeOf(strcutType);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(bytes, offset, buffer, size);
return Marshal.PtrToStructure(buffer, strcutType);
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
然后我遇到了这个问题:
//I defined a simple struct with an ushort member
[StructLayout(LayoutKind.Sequential, Pack = 2)]
struct S
{
public ushort a;
}
//Then I define a byte[]
byte[] bArr;
bArr[0] = 0;
bArr[1] = 1;
//Convert to struct
S s = (S)BytesToStruct(bArr, typeof(S));
//Then s.a = 0x0100 not 0x0001
struct to byte []也是一样的。 ushort的2个字节是相反的。 我该如何解决这个问题?
答案 0 :(得分:2)
现在大多数处理器都使用Little-Endian字节排序(最低有效字节优先)。网络字节排序是传统的Big-Endian,因此您通常需要镜像字节顺序。您可以使用System.BitConverter.IsLittleEndian
提到的ntohs()的.Net等价物(奇怪地)位于System.Net.IPAddress.NetworkToHostOrder()
您还可以编写自己的机制,使用位移和逻辑OR直接以正确的顺序读取字节。
答案 1 :(得分:1)
网络字节顺序和主机字节顺序之间存在差异。
通常,至少在C中,您使用ntohl(),ntohs()和朋友在从套接字读取时将网络字节顺序转换为主机顺序。
答案 2 :(得分:1)
问题在于系统上short
的字节顺序。看看this question about endianness,这可能会提供一些指示(双关语无意)。
此外,我建议在BytesToStruct
的类型中使struct
通用:
static S BytesToStruct<S>(byte[] bytes, int offset = 0)
所以可以用
调用它BytesToStruct<S>(bArr)
而不是目前
(S)BytesToStruct(bArr, typeof(S))