`
tcspecial
  • 浏览: 897521 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

protobuf 格式分析

阅读更多

 

protobuf 是谷歌出品一款高性能序列化框架,优点序列化后报文数据小,支持多种多种编程语言(c/c++,java,php,python等主流语言),缺点二进制不可读这倒不重要。

 

一. 安装

下载源码编译

 

二. 开发流程

2.1 准备helloworld.proto文件

package com;

message helloworld{
    required int32 id = 1;
    required string str = 2;
    optional int32 age = 3;
} 

 

 

Required 必须字段

Optional 可选字段,用的较多,便于后期平滑升级系统

Repeated 重复字段,相当于传递一个数组

 

Num 1,2,3 字段序号,不能重复

package 包名,c++中对应namespace,java对应包名

 

常用数据类型,与c/c++数据结构比较对应

bool

int32/uint32 int64/uint32

float double

string 只能处理ASCII字符

bytes 用于处理多字节语言字符,如中文

enum 枚举

 

2.2 生成各语言bundle

protoc -I=. --cpp_out=. helloworld.proto
protoc -I=. --java_out=./java helloworld.proto

 

 

2.3 网络测试

protobuf 最大的优势是跨语言,下面通过C++ udp server来处理java客户端消息。

 

C++ UDP Server:  

/**
 * C++ Udp server
 */ 
void udpServer()
{
        int s;
        struct sockaddr_in addr_serv;
        struct sockaddr_in client;

        s = socket(AF_INET, SOCK_DGRAM, 0);

        memset(&addr_serv, 0, sizeof(addr_serv));
        addr_serv.sin_family = AF_INET;
        addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);
        addr_serv.sin_port = htons(PORT_SERV);

        bind(s, (struct sockaddr*)&addr_serv, sizeof(addr_serv));

        int n;
        char buff[BUFF_LEN];
        socklen_t len;

        while(1)
        {
                len = sizeof(client);
                n = recvfrom(s, buff, BUFF_LEN, 0, (struct sockaddr*)&client, &len);

                // unserialize
                helloworld rmsg;
                rmsg.ParseFromArray( buff, BUFF_LEN );
                printf( "Recv: %s\n", rmsg.DebugString().c_str() );
        }
}

 

Java UDP Client:

/**
 * UDP 发送pb数据包
 */
public static void sendPbPacket() {
	// Builder 
	Helloworld.helloworld.Builder builder = Helloworld.helloworld.newBuilder();
	builder.setId(505100).setStr("hello world");
	builder.setAge(18);
	
	// Make object
	Helloworld.helloworld hw = builder.build();
	System.out.println( hw.toString() );

	// 序列化
	byte[] buf = hw.toByteArray();
	try {
		// 反序列化
		Helloworld.helloworld hw1 = Helloworld.helloworld.parseFrom(buf);
		System.out.println( hw1.toString() );
	} catch (InvalidProtocolBufferException e) {
		e.printStackTrace();
	}

	// UDP发送
	DatagramSocket client = null;
		
	try {
		client = new DatagramSocket();

		InetAddress addr = InetAddress.getByName(host);
		DatagramPacket sendPacket = new DatagramPacket(buf, buf.length, addr, port);
		client.send(sendPacket);
	} catch (Exception e) {
		e.printStackTrace();
	}finally{
		client.close();
	}
}

 

服务端打印:

Recv: id: 505100
str: "hello world"
age: 18

   可见 protobuf 能完美跨语言间进行序列化过程。

 

 

三. protobuf 格式分析

protobuf编码其实类似tlv(tag length value)编码,其内部就是(tag, length, value)的组合,其中tag由(field_number<<3)|wire_type计算得出,field_number由我们在proto文件中定义。

tlv

  

Wireshark将上述通信过程抓包。数据包:

 pb data

 

 

数据段,共19字节:

08 8c ea 1e 12 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64 18 12 

 

1. int id = 505100 

08 08 = (1<<3)|0,id序号,从上表查int32对应的Type为0  

8c ea 1e 三字节表示数字505100

 

505100为什么为0x8cea1e呢,下面是转换过程:

十进制: 505100 

二进制: 1111011010100001100

按照每7位拆: 001 1110 110 1010 000 1100

交换高低位,填充高位(1或0):1000 1100 1110 1010 0001 1110

十六进制:   0x08 0x0c 0xe  0xa  0x1  0xe

 

2. string str = "hello world";

12 0x12 = (2<<3)|2 

0b 长度为11

68 65 6c 6c 6f 20 77 6f 72 6c 64 hello world

 

3. int age = 18

18 0x18 = (3<<3)|0

12 十进制18 

  

 

 

 

 

  • 大小: 24.2 KB
  • 大小: 23.4 KB
分享到:
评论

相关推荐

    protobuf格式解析工具

    protobuf_decoder-master

    python开发一个解析protobuf文件的简单编译器

    最近刚刚用python写完了一个解析protobuf文件的简单编译器,深感ply实现词法分析和语法分析的简洁方便。乘着余热未过,头脑清醒,记下一点总结和心得,方便各位pythoner参考使用。 ply使用 简介 如果你不是从事...

    protobuf-tool:一个动态解析Protobuf文件的测试工具

    protobuf-tool 一个动态解析Protobuf的测试工具。

    protobuf-net-master

    Protobuf-net 来解析 google protobuf 格式的通信数据,因为 GOOGLE 自带支持的语言里不包括 C#,所以需要用到第三方的开源库 Protobuf-net 。

    ProtoBuf.js

    ProtoBuf.js是基于ByteBuffer.js的Protocol Buffers纯Javascript实现。主要功能是解析.proto 文件...目前我在一个node-webkit中使用protobuf格式于服务端进行数据交互(服务端是按照旧c++客户端要求实现的protobuf)。

    google protobuf

    protocolbuffer 是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了三种语言的实现: java 、 c++ 和 python ,每一种实现都包含了相应语言的 编译器 以及库文件。由于它是一种二进制的格式,...

    protobuf-cpp-3.11.2.tar.gz

    相比较XML和JSON格式,protobuf更小、更快、更便捷。google protobuf是跨语言的,并且自带了一个编译器(protoc),只需要用它进行编译,可以编译成Java、python、C++、C#、Go等代码,然后就可以直接使用,不需要再写...

    使用爬虫获取bilibili弹幕, 支持protobuf格式的全弹幕抓取.zip

    其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始...

    protobuf.rar

    相比较XML和JSON格式,protobuf更小、更快、更便捷。google protobuf是跨语言的,并且自带了一个编译器(protoc),只需要用它进行编译,可以编译成Java、python、C++、C#、Go等代码,然后就可以直接使用,不需要再写...

    C#版protobuf如何实现http方式二进制传输

    Protocol buffers是一种编码方法构造的一种有效而可扩展的格式的数据。 谷歌使用其内部几乎RPC协议和文件格式的所有协议缓冲区。 C#protobuf如何实现http方式二进制传输的一个例子及说明文档

    Google.Protobuf.dll

    Google.Protobuf.dll,C#用protobuf类库,用于生成和解析二进制文件 需要通过固定的proto文件格式成C#类

    picoproto:C ++中令人讨厌的微小Protobuf文件解析器

    微微原始C ++中令人讨厌的微小... 在许多情况下,我要做的就是将protobuf视为一种文件格式,并尽可能有效地从这些文件中读取数据。 我不需要写出protobuf对象,也不需要为每种类型自动创建访问类。 我也不希望对.

    ProtoBuf(pb)解析取值源码(递归法)

    路径格式就跟工具的一样,。如:1.2(1).1 () 内0表示第1个 1表示第2个 ....以此类推 (0)可以省略不填。代码很简单,不到100行,就用了核心库的几个循环判断还有字节集相关命令;。开源仅供参考学习,希望对学习pb...

    aggserv 用于接受来自树莓派的rss信号强度,通过7004端口进行分发,解析时需要遵循protobuf的定义格式

    aggserv 用于接受来自树莓派的rss信号强度,通过7004端口进行分发,解析时需要遵循protobuf的定义格式

    如何在PHP环境中使用ProtoBuf数据格式

      RPC是google公司主导的一款RPC框架,并使用protobuf作为数据传输格式,伴随gRPC框架的成熟及使用人群的增加,对于底层使用的数据格式protobuf也被越来越受到重视,而对于PHP生态而言,相关ProtoBuf介绍文档及...

    protobuf-2.4.1.zip

    2.4.1源码,很难找的 protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了三种语言的实现:java、c++ 和 python,每一种...本文的分析基于google发布的源码2.0.1版本。

    protogen:基于protobuf-net的用于将protobuf .proto解析为C#的CLI工具,可在WindowsMacLinux上使用

    目的protobuf,协议缓冲区-Google的数据交换格式 protobuf-net,C#实现,由Marc Gravell提供, protogen.exe是protobuf-net项目随附的CLI,可以将.proto解析为C#,但仅在Windows上有效。 node-protogen-csharp,此...

    go protobuf

    理论 XML 同类、JSON 也可以用来存储此类结构化数据,...json是这些年慢慢兴起的轻量级数据交换格式。比起老大哥XML。因其更快的解析速度和更小的体积,可谓是用过的都说好。一般情况下json足够满足你的大多数需求,但

    pinus-parse-interface:解析接口为pinus-protobuf JSON

    parse TS interface to pinus-protobuf JSON解析 ts 的interface 到 pinus-protobuf用的 json格式。pinus:changelogv0.2.3:fix sort method.v0.2.2: 生成的消息做排序v0.2.1:支持 结构放到顶层 (默认的客户端不支持,...

    分享顺手写的一个protoBuff解析工具吧[pb解析工具]-易语言

    在没有proto数据结构定义文件的时候,我们想去读懂protoBuff格式的二进制字节流就需要基于数据格式解析 遂白嫖了坛友一年多的解析工具,好用!在此非常感谢三位坛友 @L1yp @7ian @wlp  ,因为乐于分享,生态就不会...

Global site tag (gtag.js) - Google Analytics