解析C#中的原始协议缓冲区的字节流 [英] Parsing a raw Protocol Buffer byte stream in C#

查看:187
本文介绍了解析C#中的原始协议缓冲区的字节流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于编码的协议缓冲区字节[] ,但不知道对象类型本身,我们怎么能打印邮件的骨架?用例是用于调试的IO的protobuf的基础,根本原因分析



如果有可以从二进制文件解析的原始协议缓冲区的字节流的现有工具 - 那太好了!另一种可以使用ProtoBuf.NET类 ProtoReader(),以保持车轮继续滚滚向前,直到我们击中了错误,但ProtoReader的使用()是不明确的。我开始如下,但无法找到如何使用 ProtoReader 类真正做到这一点很好的文档。该项目的源代码是不是非常简单的跟随要么...所以希望得到一些提示/帮助

 使用(变种FS = File.OpenRead使用(文件路径))
{
(VAR PR =新ProtoReader(FS,TypeModel.Create(),null))绑定
{
//使用ProtoReader通过字节
//印刷领域的数量,类型,大小和载荷值/字节
}
}

解决方案

首先,请注意,谷歌protoc命令行工具有一些选项可以尝试拆解原始邮件没有架构信息。随着protobuf网,你可以做类似下面 - 但我需要强调的是,的没有架构的,格式是不明确的:有更多的数据类型/格式之外还有线类型(下实际的编码格式)。在这里,我只是显示的可能的解释,但也有分析相同数据的其他方式。

 静态无效WriteTree(ProtoReader读卡器)
{
,而(reader.ReadFieldHeader()0)
{
Console.WriteLine(reader.FieldNumber);
Console.WriteLine(reader.WireType);
开关(reader.WireType)
{
情况下WireType.Variant:
//警告:这似乎是错的,如果在
//值书面签署( 锯齿) - 为
//读取曲折,加上:pr.Hint(WireType.SignedVariant);
Console.WriteLine(reader.ReadInt64());
中断;
情况下WireType.String:
//注:字符串这里只是指一些字节;可以
//是UTF-8,可能是一个BLOB,可能是一个压缩数组,
//或可能是子对象(S);示出为简单起见
Console.WriteLine UTF-8(reader.ReadString());
中断;
壳体WireType.Fixed32:
//可能是一个整数,但可能浮点
Console.WriteLine(reader.ReadSingle());
中断;
壳体WireType.Fixed64:
//可能是一个整数,但可能浮点
Console.WriteLine(reader.ReadDouble());
中断;
情况下WireType.StartGroup:
// 2子对象格式
VAR TOK = ProtoReader.StartSubItem(阅读器)之一;
WriteTree(读卡器);
ProtoReader.EndSubItem(TOK,读卡器);
中断;
默认:
reader.SkipField();
中断;
}
}
}


Given a protocol buffer encoded Stream or byte[] but NOT knowing the object type itself, how can we print the skeleton of the message? The use case is for debugging IO that's protobuf based, for root cause analysis.

If there are existing tools that can parse the raw Protocol Buffer byte stream from a binary file - that would be great! An alternative could be using the ProtoBuf.NET class ProtoReader() to keep chugging along till we hit the error but the usage of ProtoReader() isn't clear. I started as below but couldn't find good documentation on how to use the ProtoReader class to actually do it. The source code of the project wasn't very straightforward to follow either ... so would appreciate some tips/help

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
    }
}

解决方案

Firstly, note that the google "protoc" command-line tool has options to try to disassemble a raw message without schema information. With protobuf-net, you can do something like below - but I need to emphasize that without the schema, the format is ambiguous: there are more data types/formats than there are "wire types" (the actual encoding formats). Here I am just showing possible interpretations, but there are other ways of parsing the same data.

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;
        }
    }
}

这篇关于解析C#中的原始协议缓冲区的字节流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆