在C#中解析原始协议缓冲区字节流

给定协议缓冲区编码的Streambyte[]但不知道对象类型本身,我们如何打印消息的骨架? 该用例用于调试基于protobuf的IO,用于根本原因分析。

如果现有工具可以解析二进制文件中的原始协议缓冲区字节流 – 这将是很棒的! 另一种方法是使用ProtoBuf.NET类ProtoReader()来保持一致,直到我们遇到错误但ProtoReader()的使用不清楚。 我从下面开始,但找不到关于如何使用ProtoReader类实际执行它的好文档。 该项目的源代码也不是很容易遵循……所以会很感激一些提示/帮助

 using (var fs = File.OpenRead(filePath)) { using (var pr = new ProtoReader(fs, TypeModel.Create(), null)) { // Use ProtoReader to march through the bytes // Printing field number, type, size and payload values/bytes } } 

首先,请注意google“protoc”命令行工具可以选择在没有架构信息的情况下尝试反编译原始消息。 使用protobuf-net,您可以执行类似下面的操作 – 但我需要强调的是, 如果没有架构 ,格式就不明确:数据类型/格式比“线路类型”(实际编码格式)更多。 在这里,我只是展示了可能的解释,但还有其他方法可以解析相同的数据。

 static void WriteTree(ProtoReader reader) { while (reader.ReadFieldHeader() > 0) { Console.WriteLine(reader.FieldNumber); Console.WriteLine(reader.WireType); switch (reader.WireType) { case WireType.Variant: // warning: this appear to be wrong if the // value was written signed ("zigzag") - to // read zigzag, add: pr.Hint(WireType.SignedVariant); Console.WriteLine(reader.ReadInt64()); break; case WireType.String: // note: "string" here just means "some bytes"; could // be UTF-8, could be a BLOB, could be a "packed array", // or could be sub-object(s); showing UTF-8 for simplicity Console.WriteLine(reader.ReadString()); break; case WireType.Fixed32: // could be an integer, but probably floating point Console.WriteLine(reader.ReadSingle()); break; case WireType.Fixed64: // could be an integer, but probably floating point Console.WriteLine(reader.ReadDouble()); break; case WireType.StartGroup: // one of 2 sub-object formats var tok = ProtoReader.StartSubItem(reader); WriteTree(reader); ProtoReader.EndSubItem(tok, reader); break; default: reader.SkipField(); break; } } }