1.在C++中使用Protobuf
2.Protobuf入门:在linux下编译使用protobuf
3.Protocol Buffer详解(一)
4.网络数据通信—ProtoBuf实现序列化和反序列化
5.一文读懂——Protobuf
6.java项目中使用protobuf扫盲笔记
在C++中使用Protobuf
ProtoBuf的源码阅读定义和描述:
Protocol Buffers是一种语言无关、平台无关、源码阅读可扩展的源码阅读序列化结构数据的方法,它适用于(数据)通信协议、源码阅读数据存储等。源码阅读
Protocol Buffers是源码阅读源码 网址一种灵活、高效、源码阅读自动化的源码阅读结构数据序列化方法,类似于XML,源码阅读但比XML更小(3 ~ 倍)、源码阅读更快( ~ 倍)、源码阅读更简单。源码阅读
你可以定义数据的源码阅读结构,然后使用特殊生成的源码阅读源代码轻松地在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,源码阅读而不会破坏由旧数据结构编译的已部署程序。
使用 ProtoBuf教程:
在了解了ProtoBuf的基本概念之后,我们将具体了解如何使用ProtoBuf。
第一步,创建.proto文件,定义数据结构,如下所示:
我们在上例中定义了一个名为Person的消息,语法很简单,message关键字后跟消息名称。之后我们在其中定义了message具有的字段,形式为:
第二步,protoc编译.proto文件生成读写接口:
在.proto文件中定义了数据结构,这些数据结构是面向开发者和业务程序的,并不面向存储和传输。当需要把这些数据进行存储或传输时,就需要将这些结构数据进行序列化、反序列化以及读写。ProtoBuf提供相应的接口代码,可以通过protoc这个编译器来生成相应的接口代码,命令如下:
生成的.h,.cpp文件为person.pb.h,person.pb.cpp,php批发系统源码且.h的定义与proto文件的内容相关联:
第三步,编写C++业务代码:
c++业务代码对应的CMakeLists.txt为:
参考链接:
Protobuf入门:在linux下编译使用protobuf
Google Protocol Buffer(简称Protobuf)是一种由Google公司内部开发的数据标准,用于数据序列化。广泛应用于数据存储和远程过程调用(RPC)系统。它具备语言无关性、平台无关性和可扩展性,支持C++、Java和Python等语言。
编译源码包:从GitHub下载Protobuf的源代码,以2.5.0版本为例。解压后,执行配置编译命令,创建文件。编译后,文件夹中将包含bin、include和lib目录。
测试工程:将include目录下的文件按目录结构和lib/libprotobuf.a复制到测试目录。定义结构化数据Content,包含id(int)、str(string)和opt(可选成员)。使用protoc程序将Mymessage.proto文件编译成目标语言,生成Mymessage.pb.h和Mymessage.pb.cc文件。
将编译后的Mymessage.pb.o文件与Writer.cpp文件一起编译,生成log文件。Reader从log文件读取,反序列化后获得结构化数据。
Protobuf的优点在于高效、紧凑的二进制数据序列化方式,使其适合数据存储和RPC通信。然而,它缺乏复杂概念表示的能力,与XML相比在通用性上仍有不足。XML自解释性使其在文本描述方面优于Protobuf。
高级应用包括嵌套消息、Import Message和动态编译。嵌套消息如Person包含PhoneNumber,arduino智慧小屋源码用于Person中的phone域。Import Message允许在包中定义公用消息,通过包引入使用。动态编译允许在运行时处理未知的.proto文件。
编写新编译器:利用Google Protocol Buffer源代码中的protoc编译器,可以开发支持其他语言的编译器。通过实现CodeGenerator派生类,实现代码生成功能。
Protobuf的编码方式使用Varint表示数字,节省空间。Varint用一个或多个字节表示数字,值越小字节越少。消息序列化为紧凑的二进制数据流,无需分隔符,可优化大小。
Protocol Buffer详解(一)
Protocol Buffer是一种支持多平台、多语言、可扩展的数据序列化机制,与XML相比,protobuf体积更小、速度更快、使用更简单,支持自定义数据结构。通过protobu编译器,可以生成特定语言的源代码,如C++、Java、Python,protoBuf对主流编程语言都提供了支持,使得序列化和反序列化变得非常方便。
一、Message定义
这里给出一个简单的例子,是一个搜索请求的message格式。
上述例子中fields的种类都是数值型的(string和int),当然也可以指定更加复杂的fields,比如枚举类型enum,maven不要打出源码或者是嵌套的message类型。
1、分配field编号
上述例子中每个field都被分配了一个编号,这个编号是该field的唯一标识。需要注意的是,标识1-在编码时只占用一个字节,-占用两个字节,因此为了进一步优化程序,对于经常出现的element,建议使用1-作为其唯一标识;对于不经常使用的element,建议使用-。编号的范围是1-2^(-是系统预留的,不要使用)。
2、field类型
message中的field类型包含以下两种(proto3):
(1)singular
(2)repeated:该类型的field可以在message中重复使用(类似于数组),它们的顺序会被保存,通过索引进行检索,数值类型的repeated默认使用packed编码方式。
3、多message结构
在一个proto文件中可以定义多个protobuf。
4、reserved field类型
在开发过程中可能会涉及到对proto文件中message各个fields的修改,可能是更新、删除某个field及其表示,这样可能会导致调用的服务失败。其中一个防止这种问题的方式是,确保你要删除的field的标识(或是名字)是reserved,具体protobuf的编译器会决定未来这个field表示能否被使用。
5、编译结果
对于C++开发者来说,使用protoc编译一个proto文件之后,会生成pb.h和pb.cc两个文件。
二、数值类型
具体proto类型对应生成类中的类型可以参考官方文档。
三、默认值
对于string和byte类型,Directshow264源码默认值为空;对于bool类型,默认值是false;对于数值类型,默认值是0;对于枚举类型,默认值是第一个枚举值,默认为0;对于message类型,默认值由编程语言决定;对于repeated field,默认值为空。
四、枚举类型
当采用枚举类型的之后,枚举中的值都是预先定义好的,对于上述例子,我们可以再额外增加一个枚举类型corpus,具体如下。
通常枚举类型的第一个值初始化为0,而且在message中使用枚举类型,必须要给定一个为0的值,而且这个为0的值应该为第一个元素。
也可以给不同的元素以相同的alias,但是需要指定option allow_alias = true;具体如下。
除此之外枚举类型不仅可以定义在message内部,也可以定义在message外部,而且在不同message中可以重用enum。
在更改枚举类型field时,为保证系统运行正常,同样可以指定reserved数字标识和命名。
五、使用其他message类型
1、同文件引用
具体如下:
2、不同文件引用
引用其他proto文件中定义好的message类型,具体如下。
有时我们会对引用的proto文件进行更改,比如将其内容移动到另外一个地方,这样我们就需要对调用方import路径进行更改,当调用方非常多的时候,这种方法是非常低效的,protobuf提供一种机制,我们可以在原有位置提供一个新位置proto文件的“副本”,通过使用import public表示来实现,具体可以参考如下例子。
这时编译器就会在某些固定目录下查询import的proto文件(具体在命令行编译的时候,由-I/—proto_path指定),如果上述路径找不到,编译器会在调用路径进行查找。通常将—proto_path设置为项目的根目录,然后import的时候使用完整的路径名。
3、使用proto2中的message类型
proto2中的枚举类型无法直接使用。
六、嵌套类型
具体如下。
在parent message之外调用嵌套的message可以用如下方式:SearchResponse.Result,嵌套结构可以更加复杂,具体如下:
七、更新message类型
当现有的message已经无法满足现有业务需要,你需要更新你的message类型以支持更复杂的业务,这就涉及到向后兼容的问题了,为保证已有服务不受影响,需要遵守以下的一些规定:
1、不要更改已经存在的fields的数字标识
2、如果添加新的field,利用旧代码序列化得到的message可以使用新的代码进行解析,你需要记住各个元素的默认值。新代码创建的field同样可以由旧代码进行加解析
3、field可以被删除,但是需要保证其对应的数字标识不再被使用,你可以通过加前缀的方式来重新使用这个field name,或者指定数字标识为reserved来避免这种情况
4、int、int、uint、uint、bool这些类型都是互相兼容的,并不会影响前向、后向兼容性
5、sint和sint之间是互相兼容的,但是和其他数字类型是不兼容的
6、string和bytes是互相兼容的,只要使用的是UTF-8编码
7、如果byte包含message的编码版本,则嵌套的message和bytes兼容
8、flexed兼容sfixed,fixed,sfixed
9、enum兼容 int, uint, int, and uint。对于这个值在转化时,不同语言的客户端处理方式会有所不同
感兴趣的小伙伴可以关注公众号:独立团丶
网络数据通信—ProtoBuf实现序列化和反序列化
Protobuf实现序列化和反序列化 本文将介绍如何通过Protobuf实现网络数据通信,具体案例中我们构建一个通讯录应用,包含客户端和服务器端的交互。主要需求包括: 客户端可执行的操作:新增联系人、删除联系人、查询通讯录列表、查询联系人详细信息。 服务器端提供增删查能力,并确保数据持久化。 客户端与服务器间交互数据使用Protobuf。 环境搭建 选择cpp-/yhirose/cpp-... CentOS环境注意事项 在CentOS下,若使用自带的g++版本(如4.8.5,发布于年),在编译项目时可能遇到问题。解决方法是升级gcc/g++至更高版本。 约定双端交互接口新增联系人
删除联系人
查询通讯录列表
查询联系人详细信息
约定双端交互req/resp 设计了多个protobuf文件用于定义请求和响应结构,包括base_response.proto、add_contact_request.proto至find_all_contacts_response.proto等。 相关视频推荐高性能服务器通信协议设计的奥秘:XML、JSON、Protobuf性能对比分析
Protobuf序列化协议工程应用方法和实践分析
qq微信即时通讯技术细节:方案选择
C/C++ Linux服务器架构师学习资料分享群:(包含C/C++、Linux、golang等技术资料)
客户端代码实现main.cc:主程序
ContactException.h:异常类定义
ContactsServer.h:客户端通讯录服务端定义
ContactsServer.cc:客户端通讯录服务实现
服务端代码实现定义通讯录结构(contacts.proto)
main.cc:服务端主程序
ContactException.h:异常类定义
ContactsServer.h:通讯录服务定义
ContactsServer.cc:通讯录服务实现
Utils.h:工具类定义
ContactsMapper.h:数据持久化接口定义
ContactsMapper.cc:数据持久化接口实现
注:在实际应用中,应将通讯录数据存储至数据库,此处为简化流程,以本地文件作为数据存储。一文读懂——Protobuf
快速理解Protocol Buffers
Protocol Buffers(简称Protobuf),是Google为内部通信和数据存储设计的一种高效轻量级的数据结构格式。全球已有超过,种报文格式定义和,个.proto文件应用于RPC系统和持久化存储。它的优势在于结构化数据的序列化与跨语言、平台的兼容性,适用于即时通讯和数据存储等领域。 与XML和JSON相比,Protobuf体积更小,解析速度更快,特别适合像即时通讯这样对数据传输效率要求高的场景。它的核心特性体现在简化了服务端开发:服务端间通信只需关注接口方法(service)和参数(message),无需关注底层协议和字段解析,大大降低了开发成本。 在Proto3版本中,相较于Proto2,语法更为简洁,例如移除了"required"和"optional"等复杂的规则,强调约定而非语法。Proto3的repeated标量数值类型默认为packed编码,而Proto2默认非packed,同时增加了Go、Ruby、JavaNano等更多语言支持。 定义数据结构时,Protobuf提供一套基础数据类型,每个字段都有唯一编号,用于二进制标识。虽然编号范围广,但要避免使用~的预留区间。为了优化编码后的数据大小,高频率的字段建议使用1~范围的编号,但需留有扩展空间。 Proto3中repeated字段的规则有所变化,而Proto2中的可扩展字段规定有所不同。在编写消息类型时,可以在一个.proto文件中定义多个相关消息,方便扩展和组织。 添加注释支持C/C++风格,通过预留字段处理更新后的兼容性问题。默认值根据字段类型设定,如字符串、布尔值等。在枚举定义上,需确保第一个枚举值为0且无重复,除非启用别名选项。 使用.proto文件定义的数据结构需通过protoc编译器生成接口代码,以支持序列化和反序列化。然而,使用CMake的execute_process命令可能存在重新生成源码导致频繁编译的问题。 实例演示包括定义.proto文件、编写读写函数以及配置文件的使用,展示了如何在实际项目中应用Protocol Buffers。更多详细信息,请参考官方文档。java项目中使用protobuf扫盲笔记
最近在公司 Java 项目中接触到了 Protocal Buffers(protobuf),这个技术对于数据传输有着独特的优势,但刚开始确实一头雾水,不明白它为何存在。不少人可能会觉得直接使用类、接口编写,再通过自定义的编译过程生成 Java 文件调用,似乎有些繁琐。然而,深入理解 protobuf 的功能与机制后,不难发现它在特定场景中的价值。
protobuf 是由谷歌开源的、用于结构化数据序列化的协议,类似于 XML、JSON 等技术,但它在数据传输性能上有着显著优势。特别是在需要高性能响应速度的场景下,protobuf 生成的字节码传输效率高于 XML 和 JSON。而它以二进制形式传递数据,因此不具可读性,但这使得数据量更小,传输速度更快。
理解 protobuf 的语法和数据类型规则,对有效利用它至关重要。以下是一些基础概念:
1. required:字段必需出现一次,常用于需要明确值的数据项。通过 this 字段名 = "值" 可以赋值。
2. optional:字段可出现零次或多次,提供可选的灵活性。使用 [default = "默认值"] 可设置默认值。
3. repeated:字段可以出现任意次数,包括零次。常用于需要多个同类数据项的场景,例如 Java List 属性。
protobuf 的工作流程涉及编写 .proto 文件,定义数据结构和字段规则,然后通过编译生成对应语言的源代码(例如 Java)。这使得数据结构在多种语言间传输变得可能,简化了跨语言合作的复杂性。
总结而言,尽管开始时可能觉得 protobuf 的使用流程有些复杂,但随着对它的深入理解,它在特定应用场景中的高效性和灵活性不容忽视。通过合理利用 protobuf 的数据序列化机制,可以显著提高数据传输的性能和效率。