如何从udp数据包解析具有相同结构的消息?

时间:2015-02-24 15:17:27

标签: c# struct binary udp

我的应用程序正在侦听udp端口,并且我收到了一些带有此结构的消息。 结构条目:

{
    long price;
    char type;
    char flag;
    int amount;
    long time;
}

我接收二进制消息,但我如何解析? 我知道不安全的方法,但对我来说,这是不合适的。 我有这个功能:

[StructLayout(LayoutKind.Sequential, Pack = 1)]    
unsafe struct MyStruct
{
    public long price;
    public char type;
    public char flag;
    public int amount;
    public long time;

    public fixed byte OptionalBytes[50];
    public fixed int OptionalInts[10];

    public static MyStruct Deserialize(byte[] data)
    {
        fixed (byte* pData = &data[0])
        {
            return *(MyStruct*)pData;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您可以在byte[]对象中包装UDP数据报的MemoryStream,然后将其包装在BinaryReader中。这将允许您根据需要阅读各个字段。例如:

struct MyStruct
{
    public long price;
    public char type;
    public char flag;
    public int amount;
    public long time;

    public byte[] OptionalBytes; // 50 bytes
    public int[] OptionalInts;   // 10 ints (i.e. 40 bytes)

    public static MyStruct Deserialize(byte[] data)
    {
        MyStruct result = new MyStruct();

        using (MemoryStream inputStream = new MemoryStream(data))
        using (BinaryReader reader = new BinaryReader(inputStream))
        {
            result.price = reader.ReadInt64();
            result.type = reader.ReadChar();
            result.flag = reader.ReadChar();
            result.amount = reader.ReadInt32();
            result.time = reader.ReadInt64();

            OptionalBytes = reader.ReadBytes(50);

            if (OptionalBytes == 50)
            {
                try
                {
                    result.OptionalInts = Enumerable.Range(0, 10)
                        .Select(i => reader.ReadInt32()).ToArray();
                }
                catch (EndOfStreamException)
                {
                    // incomplete...ignore
                }
            }
            else
            {
                // incomplete...ignore
                result.OptionalBytes = null;
            }
        }

        return result;
    }
}

注意:我为“可选”字段做了一些事情;你的问题没有说明如何处理这些问题,所以我无法确切地知道对那些人来说究竟是什么。我认为上面的例子给出了足够的一般技术概念,你可以自己弄清楚如何处理这些字段。