C# 在C语言中解析原始协议缓冲区字节流#
给定一个协议缓冲区编码的C# 在C语言中解析原始协议缓冲区字节流#,c#,protocol-buffers,protobuf-net,C#,Protocol Buffers,Protobuf Net,给定一个协议缓冲区编码的流或字节[],但不知道对象类型本身,我们如何打印消息的框架?该用例用于调试基于protobuf的IO,以进行根本原因分析 如果现有的工具能够解析二进制文件中的原始协议缓冲区字节流,那就太好了!另一种方法是使用ProtoBuf.NET类ProtoReader(),直到我们遇到错误为止,但是ProtoReader()的用法还不清楚。我从下面开始,但是找不到关于如何使用ProtoReader类来实际执行它的好文档。项目的源代码也不是很容易理解。。。因此,如果您能提供一些提示/帮
流
或字节[]
,但不知道对象类型本身,我们如何打印消息的框架?该用例用于调试基于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;
}
}
}
或者在v3中:Marc,这太好了。根据您的经验,您还可以建议使用谷歌的
协议吗?我就是找不到关于它的文档。我确实使用了--decode_raw
,但不清楚如何将二进制数组(例如:.bin文件)传递给它。无法解析输入。
像以前一样使用protoc
,即使ProtoBuf能够很好地读取二进制文件/流。我想我可能缺少一些格式或参数,但现在猜猜看。没关系,我只使用ProtoBuf.NET代码。谢谢@user100003如果您认为数据是一个子对象,那么您基本上使用与StartGroup
中显示的代码完全相同的代码,即StartSubItem
,WriteTree
,EndSubItem
。更正确的方法是以byte[]
(ProtoReader.AppendBytes
)的形式获取数据,然后测试它是否(分别)正确解析为UTF-8字符串、子消息等。