c#使用封送处理进行数据包解析 [英] c# using marshalling for packet parsing
问题描述
例如,我必须解析一个以ascii代码存储在byte []中的数据包byte []用户=新的byte [] {112,114,97,116,121,117,115,104,0,0,0,0,49,50,51,0}其中前12个字节是服务器名,后4个字节是ID.
I have to parse a packet which is stored in byte[] in ascii code for example byte[] user = new byte[] {112, 114, 97, 116, 121, 117, 115, 104, 0, 0, 0, 0, 49, 50, 51, 0} where first 12 bytes are servername and last four bytes are some id.
通过遍历之前的stackoverflow帖子,我想到了这段代码
By going through previous stackoverflow posts I came up with this code
[StructLayout(LayoutKind.Explicit)]
struct packetrf
{
public ulong servername
{
get
{
return (ulong)servername1 | ((ulong)servername2 << 8) | ((ulong)servername3 << 16) | ((ulong)servername4 << 24) | ((ulong)servername5 << 32) | ((ulong)servername6 << 40) | ((ulong)servername7 << 48) | ((ulong)servername8 << 56) | ((ulong)servername9 << 64) | ((ulong)servername10 << 72) | ((ulong)servername11 << 80) | ((ulong)servername12 << 88);
}
}
[FieldOffset(0)]
public byte servername1;
[FieldOffset(1)]
public byte servername2;
[FieldOffset(2)]
public byte servername3;
[FieldOffset(3)]
public byte servername4;
[FieldOffset(4)]
public byte servername5;
[FieldOffset(5)]
public byte servername6;
[FieldOffset(6)]
public byte servername7;
[FieldOffset(7)]
public byte servername8;
[FieldOffset(8)]
public byte servername9;
[FieldOffset(9)]
public byte servername10;
[FieldOffset(10)]
public byte servername11;
[FieldOffset(11)]
public byte servername12;
[FieldOffset(12)]
public Int32 imei_msn;
};
static private pack fromByte(byte[] arr)
{
pack str = new pack();
GCHandle handle = GCHandle.Alloc(arr, GCHandleType.Pinned);
str = (pack)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(pack));
handle.Free();
return str;
}
static private void data_parser(byte[] pkt, int size, int indexno)
{
packetrf data = fromByte(pkt);
Console.WriteLine();
Console.WriteLine(data.servername);
Console.WriteLine(data.imei_msn);
Console.ReadKey();
}
public static void Main()
{
byte[] user = new byte[] {112, 114, 97, 116, 121, 117, 115, 104, 0, 0, 0, 0, 49, 50, 51, 0}
data_parser(user, 1, 2);
}
当我运行此代码时,对于服务器名,我的输出是7526488566770266736,对于imei_msn,我的输出是13106,这可能是ascii-> hex->十进制格式.现在我面临的问题是如何将这些数字转换为一些有意义的完整信息,例如第一个数字转换为显示名称的字符串,第二个数字转换为十进制格式的imei_msn?
When I run this code my output is 7526488566770266736 for servername and 13106 for imei_msn which is probably is probably ascii->hex->decimal format. Now the problem I am facing is that how can I convert these numbers to some meaning full information like first one to string showing name and second one to imei_msn in decimal format?
推荐答案
尝试使用固定大小的数组(在此处阅读 https://stackoverflow.com/a/14629106/613130 )
Try using fixed-size arrays (read here https://stackoverflow.com/a/14629106/613130)
[StructLayout(LayoutKind.Explicit)]
struct packetrf
{
[FieldOffset(0), MarshalAs(UnmanagedType.ByValArray, SizeConst=12)]
public byte[] servername;
[FieldOffset(12)]
public Int32 imei_msn;
};
然后从那里:
string serv = Encoding.ASCII.GetString(yourObject.servername).TrimEnd('\0');
或直接作为属性
public string serverName2
{
get
{
return Encoding.ASCII.GetString(servername).TrimEnd('\0');
}
}
并记住要对 byte []
中的所有'\ 0'
进行 TrimEnd
.
And remember to TrimEnd
all those '\0'
that there will be in the byte[]
.
您确定编码为 ASCII
吗?尝试在名称中加上一些带有重音符号的字母,例如àèéìòù
...也许是 UTF8
.或者可能是使用 Default
编码.
Are you sure the encoding is ASCII
? Try putting in the name some letters with accents, like àèéìòù
... Perhaps it's UTF8
. or perhaps it's using the Default
encoding.
这篇关于c#使用封送处理进行数据包解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!