Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C语言中解析原始协议缓冲区字节流#_C#_Protocol Buffers_Protobuf Net - Fatal编程技术网

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字符串、子消息等。