`
tcspecial
  • 浏览: 911544 次
  • 性别: 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格式解析工具,如"protobuf_decoder-master",是用于处理Protocol Buffers(简称protobuf)编码数据的专业工具。protobuf是由Google开发的一种数据序列化协议,它允许开发者以结构化的方式存储和传输数据,...

    Netty发送protoBuf格式数据

    本篇将深入探讨如何利用Netty框架发送ProtoBuf格式的数据。 首先,理解ProtoBuf的工作原理是基础。ProtoBuf定义了一种结构化的数据表示方式,通过.proto文件来描述数据结构。这个文件包含了消息类型、字段、字段...

    Hive 对 Protobuf 序列化文件读取.zip

    Hive原生支持的序列化/反序列化方式(SerDe)主要是Text SerDe和Writable SerDe,但它们并不直接处理Protobuf格式的数据。为了在Hive中读取Protobuf序列化的文件,我们需要使用自定义的Protobuf SerDe,如本压缩包中...

    protobuf工具ProtoGen.exe生成C#文件

    使用如下命令行导出.cs文件protogen.exe -i:Request.proto -o:Request.cs 可以看到在同目录下生成了一个Request.cs文件,这个我们想要导出的.cs类文件

    springboot集成netty,使用protobuf作为数据交换格式,可以用于智能终端云端服务脚手架

    相比传统的JSON或XML,protobuf序列化的数据更小、解析速度更快,非常适合用于性能敏感的应用场景。 在本项目中,protobuf 被用作数据交换格式,这意味着客户端和服务器之间的通信数据将以protobuf编译后的格式进行...

    源代码以及protobuf文件转换工具

    - **日志记录**:结构化的日志数据可以用protobuf格式存储,便于后续分析。 综上所述,protobuf是一种强大的数据序列化工具,广泛应用于各类IT项目中。通过学习protobuf的相关知识,开发者可以提高数据交换的效率,...

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

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

    protobuf-lua

    它与XML、JSON等格式相比,更小、更快、更简单。在Lua中使用protobuf-lua,可以方便地在各种应用程序之间交换数据,尤其是在需要高性能和低带宽消耗的场景下。 protobuf-lua的核心功能包括: 1. **编译器工具**:...

    protobuf解析xls工具

    标题中的“protobuf解析xls工具”指的是一个特定的软件或脚本,它利用Protocol Buffers(protobuf)技术来解析Excel(xls)文件,并生成Unity游戏引擎可使用的C#(cs)文件。protobuf是一种数据序列化协议,由Google...

    protobuf 测试

    `pb-c.c` 文件通常包含解析和构建protobuf消息的函数,而`_p.c`文件可能是私有实现或者辅助函数。 3. `Student.pb-c.h`:这是对应的头文件,包含了protobuf编译器生成的结构体定义和接口声明。在编写使用protobuf的...

    Protobuf简单使用及其抓包分析

    它们可能包含了使用Protobuf编译后的Java类,以及对应的服务器和客户端逻辑,展示了如何在Java应用程序中构建和解析Protobuf消息,实现服务端与客户端之间的数据交换。 总的来说,这个资料包提供了一个学习和实践...

    protobuf解析属性

    标题"protobuf解析属性"指的是在C#环境中,如何使用protobuf库来解析包含属性的结构化数据。protobuf提供了强大的序列化和反序列化功能,能够处理带有自定义属性的对象,使得数据在客户端和服务端之间能够准确无误地...

    protobuf中文学习文档

    2. **速度**: 由于protobuf采用二进制格式,解析速度远超XML/JSON,尤其在大数据量时优势明显。 3. **语义清晰**: protobuf的消息结构清晰,易于理解,但不如XML的可读性强。 **五、protobuf应用** 1. **跨平台...

    基于Protobuf动态解析在Java中的应用 包含例子程序

    Protocol Buffers(protobuf)是一种结构化数据格式标准,由Google开发,提供了序列化和反序列方法,用于存储和交换。protobuf语言中立,平台无关、可扩展。protobuf官方提供了C++、Java、Python API,也有其他语言...

    protoc(Protobuf解码解密工具)用于无原始类时反编译数据,结构分析.rar

    它允许用户在没有原始类的情况下解析protobuf数据,这对于数据分析、日志分析、网络通信等领域都有着广泛的应用。只要遵循protobuf的语法规则,便可以轻松地扩展和修改数据结构,同时保持与旧数据的兼容性。

    jmeter 5.1.1 tcp链接 发送protobuf消息到服务端,并返回结果的demo

    服务端使用Vert.x的`NetServer`接收TCP连接,接收到数据后,使用protobuf的`parseFrom()`方法解析接收到的字节数组,还原成protobuf消息对象。根据业务逻辑处理消息,然后返回响应。 7. **集成测试** 在Maven项目...

    protobuf2.6.1

    它允许你定义数据结构,然后使用专用的编译器生成在各种编程语言中使用的代码,以便轻松地读写protobuf格式的数据。 在这个压缩包中,你将找到protobuf的预编译库(lib)和可执行文件(exe),这些通常是用于编译和...

    protobufprotobufprotobufprotobuf

    Protocol Buffers的设计目标是提供一种更高效、更灵活的数据序列化方法,相比XML、JSON等格式,它在数据传输和存储时能占用更小的体积,且解析速度更快。 在protobuf的使用过程中,主要包括以下步骤: 1. 定义数据...

    Protobuf-master包

    而 Protobuf 是二进制格式,体积小,解析快。 综上,protobuf-master 包提供了完整的 Protobuf 源代码,开发者可以深入了解其工作原理,自定义编译器插件,或者对序列化库进行扩展,以满足特定需求。对于需要高效、...

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

    **protobuf-tool:动态解析Protobuf文件的测试工具** 在IT行业中,数据序列化是一个至关重要的环节,它使得程序能够将复杂的数据结构转化为可传输或存储的格式,再将其还原为原来的结构。Protocol Buffers(简称...

Global site tag (gtag.js) - Google Analytics