c#使用封送处理进行数据包解析 [英] c# using marshalling for packet parsing

查看:71
本文介绍了c#使用封送处理进行数据包解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,我必须解析一个以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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆