0

This question is somewhat extension of a question asked previously c# using marshalling for packet parsing by me. I have to parse a variable size packet although header size is fixed but data packets inside it can be of different size and may be of more than 1 type are present in same packet.

For example the packet has following fields in its header :

1) username(12 bytes)
2 password(12 bytes)
3) id_number(4 bytes)
4) may be 1 or combination of other data packets of variable size(size can be 12, 16 or 512 bytes)
5) crc(2 bytes)

Now data packets can be following

a) data packet type 1
1) size(2 bytes)
2) name(12 bytes)
3) id_number(2 bytes)

b) data packet type 2
1) size(2 bytes)
2) data(24 bytes)
3) id_number(1 byte).

So there can be either type1 or type2. It is also possible for both type to be present. My question is how can I use marshalling to parse these packets or anyone can suggest some other way. One more thing I want to add is that 1st and 3rd field of data packets will always be the data packet size(2 bytes) and data packet id number(1 byte) respectively. The 2nd field of data packets can be anything and of variable size(2, 3, 13, 18, 515).

4

1 回答 1

1

作为替代方案,您可以使用 LINQ(假设正在使用 ASCII 编码):

var packet = new byte[]{
    97, 108, 101, 120, 0, 0, 0, 0, 0, 0, 0, 0, // username
    112, 97, 115, 115, 119, 111, 114, 100, 0, 0, 0, 0, //password
    49, 50, 51, 0, // id_number
    0, 53, 0, 0, 1, // 1st data packet
    0, 54, 1, 2, 5, 2, // 2nd data packet
    49, 0 // crc
};

var username = Encoding.ASCII.GetString(packet.Take(12).ToArray());
var password = Encoding.ASCII.GetString(packet.Skip(12).Take(12).ToArray());
var idNumber = Encoding.ASCII.GetString(packet.Skip(24).Take(4).ToArray());
var data = packet.Skip(28).Take(packet.Length - 30).ToArray();
var crc = Encoding.ASCII.GetString(packet.Skip(packet.Length - 2).ToArray());

var nextDataPackedPos = 0;
var nextDataPackedPos = 0;
var dataPackets = data
    .TakeWhile(b => nextDataPackedPos < data.Length)
    .Zip(data.Skip(nextDataPackedPos), (a, b) =>
    {
        var size = Int32.Parse(
        Encoding.ASCII
            .GetString(data.Skip(nextDataPackedPos).Take(2).ToArray())
            .Trim('\0')
        );
        var result = data.Skip(nextDataPackedPos).Take(size).ToArray();
        nextDataPackedPos += size;
        return result;
    }).ToList();

代码首先将数据部分与数据包字节分开。然后它读取每个数据包的大小,并根据它创建一个大小相等的数组,其中包含数据包的字节。然后它前进到下一个数据包的开头,直到到达阵列的末尾。

于 2013-08-14T12:23:09.507 回答