Gyö*_*sek 1 c# byte bytearray marshalling
我从服务器的源代码中获得了以下C结构,并且有许多类似的结构:
// preprocessing magic: 1-byte alignment
typedef struct AUTH_LOGON_CHALLENGE_C
{
// 4 byte header
uint8 cmd;
uint8 error;
uint16 size;
// 30 bytes
uint8 gamename[4];
uint8 version1;
uint8 version2;
uint8 version3;
uint16 build;
uint8 platform[4];
uint8 os[4];
uint8 country[4];
uint32 timezone_bias;
uint32 ip;
uint8 I_len;
// I_len bytes
uint8 I[1];
} sAuthLogonChallenge_C;
// usage (the actual code that will read my packets):
sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; // where buf is a raw byte array
Run Code Online (Sandbox Code Playgroud)
这些是TCP数据包,我需要实现一些在C#中发送和读取它们的东西.最干净的方法是什么?
我目前的做法涉及到
[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct foo { ... }
Run Code Online (Sandbox Code Playgroud)
还有很多fixed可以读写的语句,但感觉很笨重,而且由于数据包本身不是固定的长度,我觉得使用它并不舒服.此外,它还有很多工作要做.
但是,它确实很好地描述了数据结构,并且协议可能会随着时间而改变,因此这可能是维护的理想选择.
我有什么选择?用C++编写它并使用一些.NET魔法来使用它会更容易吗?
澄清:我还需要处理字节序问题和空填充字符串.
我将创建一个本机C#类来表示数据包及其数据(不是尝试匹配有线格式的数据),并BinaryReader在构造函数中传递它.让它从数据流中以适当的块读取数据:
public class LogonChallenge
{
public LogonChallenge(BinaryReader data)
{
// header
this.Cmd = data.ReadByte();
this.Error = data.ReadByte();
this.Size = data.ReadUInt16();
// etc
}
}
Run Code Online (Sandbox Code Playgroud)
如果您有多个共享公共标头或其他前导字段的数据包类型,则可以使用继承来避免重复.本BasePacket类可能读取和填充头字段,而LogonChallenge类将继承BasePacket并开始调用基类的构造后读的挑战领域.
| 归档时间: |
|
| 查看次数: |
888 次 |
| 最近记录: |