正在封送可变大小的数据包

本文关键字:数据包 | 更新日期: 2023-09-27 18:27:41

这个问题在某种程度上是我之前使用编组进行数据包解析时提出的问题的扩展。我必须解析一个可变大小的数据包,尽管报头大小是固定的,但其中的数据包可以是不同大小的,并且可能是一个以上类型的数据包。

例如,数据包的报头中有以下字段:

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)

现在数据包可以跟随

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).

所以可以有类型1或类型2。这两种类型也有可能同时存在。我的问题是,我如何使用编组来解析这些数据包,或者任何人都可以提出其他方法。我想补充的一件事是,数据包的第一和第三字段将始终分别是数据包大小(2字节)和数据包id号(1字节)。数据包的第二字段可以是任何大小可变的字段(2,3,13,18515)。

正在封送可变大小的数据包

作为替代方案,您可以使用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();

该代码首先从数据包字节中分离出数据段。然后,它读取每个数据包的大小,并在此基础上创建一个大小相等的数组,其中包含数据包的字节。然后,它前进到下一个数据包的开头,直到到达数组的末尾。