我有一个TCP客户端,它将数据包放在一个结构中
using System.Runtime.InteropServices; [StructLayoutAttribute(LayoutKind.Sequential)] public struct tPacket_5000_E { public Int16 size; public Int16 opcode; public byte securityCount; public byte securityCRC; public byte flag; [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.I1)] public byte[] blowfish; public UInt32 seedCount; public UInt32 seedCRC; [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 5, ArraySubType = UnmanagedType.I1)] public UInt32[] seedsecurity; }
我用来将数据包放入结构中的代码是:
tPacket_5000_E packet = new tPacket_5000_E(); GCHandle pin = GCHandle.Alloc(data, GCHandleType.Pinned); packet = (tPacket_5000_E)Marshal.PtrToStructure(pin.AddrOfPinnedObject(), typeof(tPacket_5000_E)); pin.Free();
现在,在我继续之前,我必须告诉你我正在将这个项目从C++转换为C#.
这就是问题:
tPacket_5000_E的最后3个成员是Int32(我也尝试过UInt32),这是C++中的DWORD.这三个成员之前的值(非 Int32)与C++中的值相同.(我在C++和C#项目中都注入相同的数据包).
但是,这三个成员有不同的价值观.
在C++中,值是(正确的):
seedCount:0x00000079
seedCRC:0X000000D1
SeedSecurity:
- [0]:0x548ac099
- 1:0x03c4d378
- [2]:0x292e9eab
- [3]:0x4eee5ee3
- [4]:0x1071206e
在C#中,值是(不正确):
seedCount:0xd1000000
seedCRC:0x99000000
SeedSecurity:
- [0]:0x78548ac0
- 1:0xab03c4d3
- [2]:0xe3292e9e
- [3]:0x6e4eee5e
- [4]:0x00107120
两个应用程序中的数据包是相同的
byte[] data = new byte[] { 0x25, 0x00, 0x00, 0x50, 0x00, 0x00, 0x0E, 0x10, 0xCE, 0xEF, 0x47, 0xDA, 0xC3, 0xFE, 0xFF, 0x79, 0x00, 0x00, 0x00, 0xD1, 0x00, 0x00, 0x00, 0x99, 0xC0, 0x8A, 0x54, 0x78, 0xD3, 0xC4, 0x03, 0xAB, 0x9E, 0x2E, 0x29, 0xE3, 0x5E, 0xEE, 0x4E, 0x6E, 0x20, 0x71, 0x10};
点击这里查看更多信息
为什么结构中的最后三个成员是不同的以及如何解决它们?
提前致谢!
我希望你的问题的根源是三个字节的值
public byte securityCount; public byte securityCRC; public byte flag;
导致下一个32位值不是字对齐的,并且您的两组代码以不同方式添加(或不添加)内部填充.
我希望不同的包装看起来像这样:
C++ C# ================================ ================================ [size ][opcode ] [size ][opcode ] [secCnt][secCrc][flag ][blow0 ] [secCnt][secCrc][flag ][blow0 ] [blow1 ][blow2 ][blow3 ][blow4 ] [blow1 ][blow2 ][blow3 ][blow4 ] [blow5 ][blow6 ][blow7 ][seedCou [blow5 ][blow6 ][blow7 ]..PAD... nt ][seedCRC [seedCount ] ][seedSec [seedCRC ] urity0 ][seedSec [seedSecurity0 ] urity1 ][seedSec [seedSecurity1 ] urity2 ][seedSec [seedSecurity2 ] urity3 ][seedSec [seedSecurity3 ] urity4 ] [seedSecurity4 ]
...用C#插入一个填充字节,导致后面的值关闭一个字节.
你可以尝试使用
[StructLayout(LayoutKind.Sequential,Pack=1)]
在结构定义之前,应该使用尽可能少的空间.
掌握C#中的Structs有一些关于如何/为什么会发生这种情况的好信息.