barriers / 阅读 / 详情

在项目中使用Protobuf协议实现数据传输(二)

2023-08-25 05:24:01
共1条回复
snjk

上篇已经简单的分析了什么是ProtoBuf协议的优缺点、简单的环境配置、项目中的简单使用和一些编写.Proto文件的注意点,下面我们更加深入一下ProtoBuf的语法及高级使用(非常感谢Carson_Ho大神的博文指导)

作用 :防止不同 .proto 项目间命名 发生冲突

ProtoBuf包的解析过程如下 :

作用 :影响 特定环境下 的处理方式,但不改变整个文件声明的含义

常用Option选项 :(因为使用有限,简单列举常见的)

作用 :真正用于描述 数据结构

在.proto消息模型中主要有 消息对象&字段

组成 :字段 = 字段修饰符 + 字段类型 +字段名 +标识号(主要针对proto2以前版本)

字段 = 字段类型 +字段名 +标识号(主要针对proto3及以后版本)

一个消息对象 可以将 其他消息对象类型 用作字段类型

关于ProtoBuf在项目中的实践的高级用法请关注:下一篇博客:在项目中使用Protobuf协议实现数据传输(三)

相关推荐

PROTO什么意思?

proto英 [pru0259u028atu0259]美 ["proto]n. 原型;样机;典型n. (Proto)人名;(意)普罗托
2023-08-19 11:26:531

proto是什么阶段

proto打样, 料件及整机模具开发调试阶段 EVT, Engineering Validation Test 是针对工程原型机的验证,对象很可能是一大块开发板,或是很多块开发板;关键是要有足够时间和样品。 通常,如果是新平台,需要花的时间和精力可能更多,会有很多问题要解决,甚至有很多方案要对比;而修改既有产品的话,这个阶段会简单很多,甚至省略。 这一阶段的重点是尽可能多的发现设计问题,以便及早修正;或者说设计可行性的验证。同时检查是否有规格被遗漏。 主要由研发部门来执行。
2023-08-19 11:27:011

PROTO什么意思?

proto-表示“第一, 主要”之义例如:表示“第一, 主要, 原始, 最初”, 如:proto -Arabic
2023-08-19 11:27:082

proto是意大利哪个地方?

普拉托镇(Prato),位于意大利中北部的托斯卡纳地区。在佛罗伦萨西北13公里的比森齐奥河畔。
2023-08-19 11:27:171

现代汽车体系中PROTO 是什么意思

Proto是一家南韩的汽车公司, 地位为运动型汽车.应该不是一家很大的车厂, 主要通过与现代,起亚等大公司合作来生产自己品牌的车. 1997年开始至今没几个车型. 不是很出名的. 2001年proto给韩国总统府,(在职总统的家),定制了一款LIMO, 豪华轿车
2023-08-19 11:27:321

"proto"是什么品牌中文名是叫什么

思派朗 编辑来自韩国Proto汽车公司,只不过现在Proto已经被翱欧邻(OULLIM)投资集团收购的超级跑车,此车改写了韩国没有超级跑车的历史。
2023-08-19 11:27:431

ProtoBuf简介

ProtoBuf是一种无关语言,无关平台的序列化结构数据的方法,可用于通信协议、数据存储等 XML:数据较为冗余,需要成对的闭合标签 JSON:使用键值对方式,压缩了一定的数据空间并且具有可读性 ProtoBuf:适合高性能,对响应速度有要求的数据传输场景,ProtoBuf是二进制数据格式,需要解码和编码,数据本身不具有可读性,只能反序列化后才能读到真正的数据。序列化后的数据相比json和xml很小,适合网络传输;序列化和反序列化比json的处理速度更快。 XML、JSON 更注重数据结构化. ProtoBuf更注重数据序列化,关注效率、空间、速度 数据类型分为两大类: 复合数据类型:枚举和message类型 标准数据类型:整型,浮点,字符串 规则的修饰符: required 字段必须出现1次 optional 字段可出现0次或1次 repeated 字段可出现多次(包括0) 标准数据类型: proto与python类型对应 例如:
2023-08-19 11:27:571

macbook下eclipse使用proto

先确认你的Mac上是否已安装java运行环境。具体步骤如下:1、进入终端,输入java-version,如果返回了java版本号,则说明已安装,否则,会弹出先安装java运行环境的提示。2、访问Oracle官网,浏览到首页的底部菜单,选择JAVA选项下面的DOWNLOADJAVAFORDEVELOPERS。3、点击“JDKDOWNLOAD”按钮。4、选择“AcceptLisenceAgreement”同意协议。5、点击MacOSXx64后面的下载链接。勾选ACCEPTLICENSEAGREEMENT,选择下面MAC开头的下载包。6、下载完成后点击安装包,按提示即可完成安装。7、打开终端,输入:/usr/libexec/java_home-V。8、会出现3个红框内依次为:输入命令,当前Mac已安装jdk目录,Mac默认使用的jdk版本。其中Contents下的Home文件夹,是该JDK的根目录。最后根据进程设置环境变量即可,具体代码可在网上查询到。
2023-08-19 11:28:451

c语言中PROTO是什么意思

这不是写得很明白吗?#if _HW_ #define PROTO #else #define PROTO extern#endifPROTO是extern的别名
2023-08-19 11:28:552

proto 转json 值类型错误 python

解决方法如下:1,protobuf下载安装。2,新建目录example。3,上面步骤做好之后,下面我们需要用python实现基于protobuf协议将json转化为pbstring,将pbstring转成json。
2023-08-19 11:29:031

电脑网络信息:Proto. Local Address Foreign Address. State TCP和UDP 等各是什么意思?定义是?

你这个可以通过netstat-b命令来查看!Proto你的电脑连接对方服务器或电脑所用协议Localaddress本地计算机地址和连接目的地址所用的端口foreignaddress你的电脑连接目的IP和对方跟你连接所用的端口state是提示你连接的状态是否成功TCP和UDP都是网络协议
2023-08-19 11:29:141

怎么样编写Protobuf的.proto文件

ProtoBuf java 包编译ProtoBuf的官方下载包并不包含jar文件,需要用户自己configure/make….来自行编译。由于Windows上没有编译环境,就用了一个笨一点方法处理了。分别下载:protobuf-2.4.1.zip ProtoBuf的源文件(包含了C++/Java/Python)的源文件protoc-2.4.1-win32.zip 已经编译过的用于Windows平台的protoc命令(该命令用于将.proto文件转化为Java或C++源文件)。分别解析这两个文件,你可以在protoc-2.4.1-win32.zip解压后的文件中找到一个protoc.exe文件,将其copy到protobuf-2.4.1/src目录下,然后进入protobuf-2.4.1/java,执行:mvn install
2023-08-19 11:29:221

android studio怎么编译proto

方案是:1、在build.gradle中增加dependencies { compile fileTree(dir: "libs", include: ["*.jar"]) compile group:"com.google.protobuf",name:"protobuf-java",version:"2.5.0" //这个是关键的一句话,对于这个version是从你的本地maven存放的目录, 进入到 .m2 epositorycomgoogleprotobufprotobuf-java目录下,看到的那个数字文件夹的名字,就是你的version,
2023-08-19 11:29:291

Google protobuf中的ByteString怎么转化成为string类型

2.下载一个protobuf-java-2.4.1.jar文件(注意,要与你刚才下的proto.exe版本相同)然后就开始开发了。步骤:1.用记事本编写一个.proto文件:}如:编写的是test.protopackage protobuf;option java_package = "com.sq.protobuf";option java_outer_classname = "FirstProtobuf";message testBuf {required int32 ID = 1;required string Url = 2;}将其放在与刚解压的protoc.exe同级目录中。2.在cmd中,到protoc-2.4.1-win32文件夹下,执行E:protoc-2.4.1-win32> protoc.exe --java_out=./ test.proto则可以找到的一个生成的FirstProtobuf.java文件。3.在MyEclipse中新建一个java project,建立包com.sq.protobuf,然后将刚才生成的FirstProtobuf.java文件放在其下面。此时会报错,因为没有引入jar包,在package视图下,将protobuf-java-2.4.1.jar引入,即可解决问题。
2023-08-19 11:29:491

为什么Protobuf的默认序列化格式没有包含消息的长度与类型

编译后protobuf形成对应的文件,加入工程,创建你的消息对象,给里面的成员赋值,然后将这个对象转化为字节流,用socket函数直接write出去即可。
2023-08-19 11:29:582

java中.proto文件怎么用

用cd命令打开文件所在目录,例如文件在E: oolsComputerprotoc-2.5.0-win32下cmd命令:e:E:>cd tools
2023-08-19 11:30:081

python如何通过protobuf实现rpc

由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc。rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行google,这里只是做个简单的介绍。rpc的主要功能是让分布式系统的实现更为简单,为提供强大的远程调用而不损失本地调用语义的简洁性。为了实现这个目标,rpc框架需要提供一种透明调用机制让使用者不必显示区分本地调用还是远程调用。rpc架构涉及的组件如下:客户方像调用本地方法一样去调用远程接口方法,RPC 框架提供接口的代理实现,实际的调用将委托给代理RpcProxy 。代理封装调用信息并将调用转交给RpcInvoker 去实际执行。在客户端的RpcInvoker 通过连接器RpcConnector 去维持与服务端的通道RpcChannel,并使用RpcProtocol 执行协议编码(encode)并将编码后的请求消息通过通道发送给服务方。RPC 服务端接收器 RpcAcceptor 接收客户端的调用请求,同样使用RpcProtocol 执行协议解码(decode)。解码后的调用信息传递给RpcProcessor 去控制处理调用过程,最后再委托调用给RpcInvoker 去实际执行并返回调用结果。protobuf rpc在上面组件中主要扮演RpcProtocol的角色,使得我们省去了协议的设计,并且protobuf协议在编码和空间效率都是上非常高效的,这也是很多公司采用protobuf作为数据序列化和通信协议的原因。同时protobuf rpc定义了一个抽象的rpc框架,如下图所示:RpcServiceStub和RpcService类是protobuf编译器根据proto定义生成的类,RpcService定义了服务端暴露给客户端的函数接口,具体实现需要用户自己继承这个类来实现。RpcServiceStub定义了服务端暴露函数的描述,并将客户端对RpcServiceStub中函数的调用统一转换到调用RpcChannel中的CallMethod方法,CallMethod通过RpcServiceStub传过来的函数描述符和函数参数对该次rpc调用进行encode,最终通过RpcConnecor发送给服务方。对方以客户端相反的过程最终调用RpcSerivice中定义的函数。事实上,protobuf rpc的框架只是RpcChannel中定义了空的CallMethod,所以具体怎样进行encode和调用RpcConnector都要自己实现。RpcConnector在protobuf中没有定义,所以这个完成由用户自己实现,它的作用就是收发rpc消息包。在服务端,RpcChannel通过调用RpcService中的CallMethod来具体调用RpcService中暴露给客户端的函数。介绍了这么多,对于怎么样用protobuf rpc来实现一个rpc肯定还是一头雾水吧,下面就用protobuf rpc来实现一个简单的python版rpc demo吧。下面直接给出demo描述PRC的proto文件,至于proto文件的编写规则可以参考protobuf官网。common.proto文件:package game;message RequestMessage{ required string message = 1;}message ResponseMessage{ required string message = 1;}game_service.proto文件:package game;import "common.proto";option py_generic_services = true;service GameService{ rpc connect_server(RequestMessage) returns(RequestMessage);}common.proto文件描述了RPC中收发的消息;game_service.proto描述了服务器导出的connect_server函数,该函数接受RequestMessage对象作为参数,并返回RequestMessage对象。在使用PRC协议时,必须加上option py_generic_services = true;可选项,要不然编译器不会生成包含connect_server函数的GameService描述。使用编译器protoc编译proto文件,具体命令为:protoc.exe --python_out=. game_service.proto编译后生成的文件为game_service_pb2.py,该文件主要是实现了GameService和GameService_Stub类。GameService_Stub类用于客户端调用者来调用GameService的服务。前面已经说了,在客户端,RpcChannel只实现了一个空的CallMethod,所以需要继承RpcChannel重新这个函数来encode消息和发送消息。在服务端RpcChannel需要调用CallMethod来调用Service中的函数。具体实现如下:class MyRpcChannel(service.RpcChannel): def __init__(self, rpc_service, conn): super(MyRpcChannel, self).__init__() self.logger = LogManager.get_logger("MyRpcChannel") def CallMethod(self, method_descriptor, rpc_controller, request, response_class, done): """"protol buffer rpc 需要的函数,用来发送rpc调用""" self.logger.info("CallMethod") cmd_index = method_descriptor.index assert(cmd_index < 65535) data = request.SerializeToString() total_len = len(data) + 2 self.conn.send_data("".join([pack("最后就是继承GameService,并实现connect_server函数了。class GameService(game_service_pb2.GameService): def __init__(self): self.logger = LogManager.get_logger("GameService") def connect_server(self, rpc_controller, request, callback): self.logger.info("%s", request.message) 至于用于网络收发消息的RpcConnector,可以使用python的asyncore库实现,具体实现在这就不讨论了。从上面的实现来看,protobuf rpc的实现主要包括编写proto文件并编译生成对应的service_pb2文件,继承RpcChannel并实现CallMethod和调用Service的CallMethod,继承Service来实现暴露给客户端的函数。
2023-08-19 11:30:161

为什么google protobuf不支持map的序列化和反序列化

现在它是支持的。proto2的文档就已经提到了Maps(Language Guide),但我用protoc2.6编译的时候,map关键字无法通过编译,protoc3.0编译正常,proto举例:message Person {required int32 id = 1;required string name = 2;optional string email = 3;map<string, string> values= 4;} 另外,官方文档(https://developers.google.com/protocol-buffers/docs/proto#Maps)说了:The map syntax is equivalent to the following on the wire, so protocol buffers implementations that do not support maps can still handle your data:message MapFieldEntry {key_type key = 1;value_type value = 2;}repeated MapFieldEntry map_field = N;
2023-08-19 11:30:251

.proto 文件怎么生成.h文件

打开命令行程序,输入如下语句: protoc -I=../script --cpp_out=../protoc ../script/Package.proto 将会产生两个名为Package.pb.cc和Package.pb.cc的文件。
2023-08-19 11:30:331

vue使用protobuf+websocket

我的教程是用protobuf生成了proto.js文件 1、运行npm install protobufjs --save 安装 2、拿到后台给的proto文件,在src里创建一个proto目录,用于存放proto文件及编译后的js文件 proto 3、运行命令 生成proto.js文件,如图 4、使用 websocket返回的数据是model.data 官方git教程 https://github.com/protobufjs/protobuf.js
2023-08-19 11:30:401

Protocol Buffers(Objective-C)踩坑指南

这篇文章是讲如何把protobuf文件的编译工作集成到Xcode中,达到在Xcode中就像添加一般的OC文件一样不进行任何多余的操作直接编译运行.proto文件的目的。 牛逼,这么智能吗?是的,就是这么智能! 笔者的公司现在所有端都在统一使用一套protobuf数据结构,免除了多端重复定义同一套数据结构的重复工作,效率很高,非常值得推荐。并且Xcode 10进行了一些小优化来增加了对Protobuf的支持,相信不久以后,Xcode对Protobuf的支持将更加智能! 至于什么是 Protobuf 和 Protobuf 语法教程,不是这篇文章的主题,请自行Google。 环境:Xcode 10+ 语言:Objective-C 话不多说,正题开始: 首先,真正的企业级项目,并不只是网上很多教程里面演示的一两个 .proto 文件,而是一批 .proto 文件目录的集合,并且是多端共享的。你会发现按照那些教程里面的讲的去做写个demo或许可以,但是真正要达到企业级别的使用的时候,还远远不够,你会遇到各种各样的坑。别问我是怎么知道的,我都是靠自己一个个踩出来的。 首先,要能编译Protobuf文件,我们得安装官方的编译器。你可以选择下面任意一种你喜欢的安装方式: 安装好后,在terminal中输入 which protoc 检测是否安装成功,如安装成功会返回文件路径: /usr/local/bin/protoc 如有问题,请自行google,不在本教程范围内。 没什么好说的,新建一个Xcode工程。使用Cocoapods引入Protobuf的库: Pod search Protobuf 选择最稳定的版本即可。 这里有两种创建.proto文件的方式: 至于文件内容,如果你熟悉protobuf语法,那随便写几行即可,如果不熟悉,那么可以copy我的测试内容: A.proto 文件内容: B.proto 文件内容: Xcode 自己并不认识 .proto文件,所以并不会自动编译它们,我们需要把 .proto编译器 自己集成到项目当中,集成的方式如下: Project --> Build Rules --> 点击+号 ,生成一个特定文件类型编译脚本。 比如: 到此处,我们有几个注意事项: 我们试试把 --proto_path 换成相对路径,看会发生什么,也就是把脚本换成 编译运行,咦~报错了。查看日志,我们可以看到这么一条log信息: 翻译过来就是在--proto_path这个参数中你必须指定.proto源文件的精确路径, protoc 太笨了,它无法搞清楚这个相对路径是不是我们要的绝对路径。google的工程师说这太他么难了。所以这里很明确了, --proto_path 的参数值,只能是proto文件根目录的绝对路径。 我们上面说了,${INPUT_FILE_PATH} 是代表编译输入源文件的绝对路径。 文档里面给的demo是: protoc --proto_path=src --objc_out=build/gen src/foo.proto src/bar/baz.proto 什么意思呢? 它说,最终编译器会把 src/foo.proto 文件编译成: build/gen/Foo.pbobjc.h 和 build/gen/Foo.pbobjc.m 文件。 而会把 src/bar/baz.proto 文件编译成 build/gen/bar/Baz.pbobjc.h 和 build/gen/bar/Baz.pbobjc.m 。 而不是 build/gen/Baz.pbobjc.h 和 build/gen/Baz.pbobjc.m 也就是说protobuf编译器最终生成的文件会自动按照文件源目录结构存放。 特别强调 并不会 自动创建 build/gen 目录,这个目录需要你提前建好。 并且,查看最终编译生成的.m文件,你会发现一些有趣的事情;比如我在A.proto中引入了B.proto文件,你会看到Protobuf最终编译出来的A.pbobjc.m文件导入文件的格式是包含文件路径的,例如: 我们注意到,上面设置的proto文件的编译输出路径是 $DERIVED_FILE_DIR , 这是为何呢? 答案是为了方便Xcode的集成。 对于自定义的编译脚本,都需要设置一个文件的输出路径. 我们点脚本框下面的Output Files下面的 + 号, 指定文件输出路径。 因为OC文件分为.h和.m文件,所以我们指定2个。 点了之后,你会发现,xcode默认给出的是 $(DERIVED_FILE_DIR)/newOutputFile , 我们将其改为 $(DERIVED_FILE_DIR)/${INPUT_FILE_BASE}.pbobjc.h 和 $(DERIVED_FILE_DIR)/${INPUT_FILE_BASE}.pbobjc.m ,并且在.m文件的 Compiler Flags 中指定为 -fno-objc-arc 代表该.m文件采用mrc编译。 编译运行,大功告成,是不可能的!!!! 你会发现又报错了: 什么意思呢? 其实就是在 DerivedSources 下找不到 A.pbobjc.m 文件。因为我们指定这个编译的输出路径在这个目录下,所以Xcode在进行OC文件的编译时会去这个目录下找,但是它找不到。为什么找不到呢?我们去这个目录下看,这个目录下确实没有 A.pbobjc.m 这个文件,但是确发现有 a/A.pbobjc.m 。原因我们已经说了,protoc最终的编译文件会自动加上目录前缀。 有人可能会说,能不能把输出文件改成 $(DERIVED_FILE_DIR)/*/${INPUT_FILE_BASE}.pbobjc.h 呢?那我们就来试下。 编译运行 what the hell? 原来,Xcode的Output Files特别蠢,它不支持类似这种通配符写法: $(DERIVED_FILE_DIR)/*/${INPUT_FILE_BASE}.pbobjc.h 。 也不支持传入任何的自定义变量。 只能是明确的文件路径和Xcode自带的环境变量,但是实际项目中,可能不只一层路径,有可能是文件夹下嵌套文件夹。 靠,那这怎么办呢? 实在没办法了,就在打算放弃的时候,咨询了我们的脚本大神,我们尝试了以下在脚本末尾再加了两行: 是不是很机智? 什么意思呢?就是说我们cd到该目录,然后找到该文件对应生成的oc文件,将其copy一份儿到根目录。怀着求神拜佛的意志,运行了以下,Perfect,终于不再报错了,到目录中查看,也正是我们想要的,所有文件都被copy出来了。 下一步,就是正常的在项目中import和使用了。 你以为到此就没有坑了吗?到此还有坑。有2点需要注意: 好了,就讲到这里吧,如果觉得文章看得不是很明白,需要一个demo。或者大神有更好的建议,请在评论区留言~ 如果文章对你有帮助,请不要吝啬你的点赞哦,你的支持是我分享的动力~ 如果大家喜欢,有时间再讲讲怎么改改AFNetworking,能直接请求后端给的 Protobuf 格式的数据~
2023-08-19 11:30:481

linux ping命令中的struct proto

可以使用,相当与函数地址作为一个常量值赋值给结构体变量函数proto_v4 = { proc_v4, send_v4, NULL, NULL, 0, IPPROTO_ICMP };等同于:proto_v4 = { &proc_v4, &send_v4, NULL, NULL, 0, IPPROTO_ICMP }即取函数地址指针。
2023-08-19 11:34:022

proto 没有set

protobufrepeated的数据类型和C++的Vector,list类似,只能传输相同的数据类型。当然,如果你为了传输多种数据类型,可以使用类似与C++union的方式,用个大消息,消息的每个字段都使用optional标记,你在业务处理的时候,每次只对一个字段赋值同样可以达到目的。另外:repeated只能表示数据有还是没有,在没有的时候,究竟是保留原有的数据不动,还是删除所有数据,这点有歧义。需要使用另外的字段进行处理。
2023-08-19 11:34:101

怎样用正则表达式删除PROTO及紧跟的()? 例void PROTO(main)(void)变为void main(void)却不删除main

s/PROTO([^.]+)/$1
2023-08-19 11:34:183

proto3怎么判断字段是否被赋值

客户端lua,通信协议是protobuf,以前用网易的proto-gen-lua,使用过程遇到些问题需要绕,比如: 1、每次更改、增加proto都要生成新的文件,代码规模剧增 2、由于lua本身,每个文件最大文件内全局local变量不能超过200个,所以当proto规模太大时...
2023-08-19 11:34:261

原核细胞基因中,有没有癌基因?

楼上的回答我很是好奇。先谈癌基因(oncogene)。楼主提到的癌基因,我的理解应该是proto-oncgene(原癌基因)。正常的proto-onc,它的功能是促进正常细胞生长、增殖、分化、发育(注意,proto-onc并非抑制细胞生长,也就是说它对细胞的增殖是正向调控的)。proto-onc的这种正向调控,导致细胞存在无限增殖潜在可能性。因而proto-onc的表达必须受到负调控因素的抑制才能使细胞有限的增殖和分化。所以真正对细胞增殖分化起直接调控(抑制)作用的是anti-onco(抑癌基因)而不是proto-onc。因此,楼上从“原核细胞也有增值、分裂。那它就有控制增殖的基因”反推“故原核细胞有癌基因”,是完全站不住脚的。 对于多细胞生物来讲,通过细胞分裂周期的调控来限制细胞的增殖分化以实现组织、器官、及个体的稳定性,这种从局部到整体的模式,其意义相信我们都能理解。但对于单细胞生物,原核细胞来讲,这种调控有什么意义?实验室里做出来的生长曲线,稳定期、衰亡期的出现只是受到营养物质及次级代谢废物等等外因的影响而产生的,并非由特定基因调控。也就是说给你一个E. coli,只要有足够丰富的营养物质,那么它就能无限增殖直至外界环境不再适于它生长。 当然,你可能可以找到病毒癌基因(virus oncogene)这个概念,然,v-onc是针对病毒的宿主细胞而非病毒本身而言的;同时,对于单细胞的酵母来讲,在它基因组中也同样发现了proto-onc,但,需要注意的是,酵母却是真核细胞。
2023-08-19 11:34:341

protobuf 怎么查看版本

protoc --version
2023-08-19 11:35:072

protobuf可变长度原理

这篇文章在你已经了解protobuf使用的基础上,更进一步的学习,如果不知道protobuf是什么?请查阅这篇文章 【golang-protobuf使用】 官网说明地址: https://developers.google.com/protocol-buffers/docs/proto3 proto文件的可变长度类型有:int32、int64、uin32、uin64、sint32、sint64 Protobuf 用的是连续位标识技术,使用每个字节的第一位来标识是否需要继续向后读。每个字节低7位用于实际的编码。 举例: 十进制:300 二进制(4个字节):00000000 00000000 00000001 1000000 protobuf编码过程 所以最终编码结果为 1 0000000 0 1100000,这样将4字节存储大小转化为2字节存储大小 目标:将10^32bit的二进制进行编码 proto文件格式 测试结果: 由测试结果可得如果高位(左边)字节为0,编码结果大小相应减少
2023-08-19 11:36:201

javascript中_proto_和__proto__的区别?左边是一条下划线,右边是两条下划线

这仅仅表示是两个不同的变量名而已,与下划线没什么必然的关系。下划线在这里就是变量名的一个组成部分而已,可以换成其他任意的字母或数字(但开头第一个下划线只能换成字母不能是数字),用下划线仅仅是程序设计者的个人爱好而已。你如果想偷懒,你甚至可以直接用a和b来分别作为两个变量名的。
2023-08-19 11:36:331

PROTO什么意思

PROTO原abbr.protoporphyrinogen 原卟啉原,初卟啉原; 答题不易答案满意采纳谢谢思密达ps:如有问题继续追问
2023-08-19 11:37:082

protobuf 怎么查看版本

protobuf版本需要在protobuf程序中查看。在protobuf程序中查看版本步骤如下所示:1、点击打开计算机,进入分区列表。2、在计算机分区列表中选择protobuf程序所在的文件夹。3、点击打开protobuf程序。4、如图所示在protobuf程序中,即可完成protobuf版本查看。
2023-08-19 11:37:161

在proto 中如何将字符串封到bytes

Configuration conf = HBaseConfiguration.create(); String tableName = "testTable"; Scan scan = new Scan(); scan.setCaching(10000); scan.setCacheBlocks(false); conf.set(TableInputFormat.INPUT_TABLE, tableName); ClientProtos.Scan ...
2023-08-19 11:38:291

android studio的proto文件放在哪

方案是:1、在build.gradle中增加dependencies { compile fileTree(dir: "libs", include: ["*.jar"]) compile group:"com.google.protobuf",name:"protobuf-java",version:"2.5.0" //这个是关键的一句话,对于这个version是从你的本地maven存放的目录, 进入到 .m2 epositorycomgoogleprotobufprotobuf-java目录下,看到的那个数字文件夹的名字,就是你的version,
2023-08-19 11:38:391

protobuf repeated 怎么用的

protobuf repeated类型的使用protobuf是Google开发的一个序列化框架,类似XML,JSON,基于二进制,比传统的XML表示同样一段内容要短小得多。通过protobuf,可以很轻松的调用相关方法来完成业务数据的序列化与反序列化。protobuf repeated类型相当于std的vector,可以用来存放N个相同类型的内容,文章将简单介绍protobuf repeated的使用。首先定义一个protobuf结构,如下:message Person { required int32 age = 1; required string name = 2;}message Family { repeated Person person = 1;}下面以例子简单说明如何使用:int main(int argc, char* argv[]){ GOOGLE_PROTOBUF_VERIFY_VERSION; Family family; Person* person; // 添加一个家庭成员,John person = family.add_person(); person->set_age(25); person->set_name("John"); // 添加一个家庭成员,Lucy person = family.add_person(); person->set_age(23); person->set_name("Lucy"); // 添加一个家庭成员,Tony person = family.add_person(); person->set_age(2); person->set_name("Tony"); // 显示所有家庭成员 int size = family.person_size(); cout << "这个家庭有 " << size << " 个成员,如下:" << endl; for(int i=0; i<size; i++) { Person psn = family.person(i); cout << i+1 << ". " << psn.name() << ", 年龄 " << psn.age() << endl; } getchar(); return 0;}
2023-08-19 11:38:512

proto-horse什么意思?

proto-horse原马proto [词典] 原型机,样机;[网络] 原; 普罗托; 协议;[例句]What"s Generated From Your. proto?从你的.proto文件生成了什么?horse 英[hɔ:s]美[hɔ:rs]n. 马; 骑马的军人,骑兵; 有脚的架; 跳马,鞍马;vt. 为…备马; 猛推或用力向上举;vi. 欲交配,,用于母马;[网络] 黑马; 跳马; 房子;[例句]A small man on a grey horse had appeared.一个骑着灰马的小个子男人出现了。[其他] 第三人称单数:horses 复数:horses 现在分词:horsing 过去式:horsed 过去分词:horsed
2023-08-19 11:39:031

c#实体转成proto message

经常会遇到把一个实体转化成另一个实体这样的情况,实体的属性一个一个手写去转化不反对,但不是啥好的方法;可以使用反射写一个通用的实体转化类,针对任何实体转化,不用再去自己手写。虽然Grpc.Tools可以将proto文件自动生成代理类,但是proto文件的手敲,还容易出错,如果接口比较复杂,定义比较多,这就很头疼了。为了解决这个问题Class2Proto诞生了,使用标准C#对象转换成proto文件,不管是新写的接口,还是老的API接口转Grpc,都没问题:1、安装nuget包:CRL.Class2Proto 2、using CRL.Class2Proto; 定义标准接口代码;运行转换方法生成proto文件;程序目录Protos成生了protoTest.proto文件
2023-08-19 11:39:161

一个案子Proto阶段的定义是什么?需要做些什么?proto后面是EVT,DVT,PVT

打样, 料件及整机模具开发调试阶段
2023-08-19 11:39:391

怎么将protobuf string类型

2.下载一个protobuf-java-2.4.1.jar文件(注意,要与你刚才下的proto.exe版本相同)然后就开始开发了。步骤:1.用记事本编写一个.proto文件:}如:编写的是test.proto package protobuf; option java_package = "com.sq.protobuf"; option java_outer_classname = "FirstProtobuf"; message testBuf { required int32 ID = 1; required string Url = 2; }将其放在与刚解压的protoc.exe同级目录中。2.在cmd中,到protoc-2.4.1-win32文件夹下,执行E:protoc-2.4.1-win32> protoc.exe --java_out=./ test.proto 则可以找到的一个生成的FirstProtobuf.java文件。3.在MyEclipse中新建一个java project,建立包com.sq.protobuf,然后将刚才生成的FirstProtobuf.java文件放在其下面。此时会报错,因为没有引入jar包,在package视图下,将protobuf-java-2.4.1.jar引入,即可解决问题。
2023-08-19 11:39:471

为什么google protobuf不支持map的序列化和反序列化

现在它是支持的。proto2的文档就已经提到了Maps(Language Guide),但我用protoc2.6编译的时候,map关键字无法通过编译,protoc3.0编译正常,proto举例:message Person { required int32 id = 1; required string name = 2; optional string email = 3; map<string, string> values= 4; } 另外,官方文档(https://developers.google.com/protocol-buffers/docs/proto#Maps)说了:The map syntax is equivalent to the following on the wire, so protocol buffers implementations that do not support maps can still handle your data:message MapFieldEntry { key_type key = 1; value_type value = 2;}repeated MapFieldEntry map_field = N;
2023-08-19 11:39:551

在 cmd 下输入netstat -an后 显示的数据是什么意思?

netstat命令是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息,在我的计算机上执行netstat后,其输出结果为: Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 2 210.34.6.89:telnet 210.34.6.96:2873 ESTABLISHED tcp 296 0 210.34.6.89:1165 210.34.6.84:netbios-ssn ESTABLISHED tcp 0 0 localhost.localdom:9001 localhost.localdom:1162 ESTABLISHED tcp 0 0 localhost.localdom:1162 localhost.localdom:9001 ESTABLISHED tcp 0 80 210.34.6.89:1161 210.34.6.10:netbios-ssn CLOSE Active UNIX domain sockets (w/o servers) Proto RefCnt Flags Type State I-Node Path unix 1 [ ] STREAM CONNECTED 16178 @000000dd unix 1 [ ] STREAM CONNECTED 16176 @000000dc unix 9 [ ] DGRAM 5292 /dev/log unix 1 [ ] STREAM CONNECTED 16182 @000000df 从整体上看,netstat的输出结果可以分为两个部分,一个是Active Internet connections,称为有源TCP连接,另一个是Active UNIX domain sockets,称为有源Unix域套接口。在上面的输出结果中,第一部分有5个输出结果,显示有源TCP连接的情况,而第二部分的输出结果显示的是Unix域套接口的连接情况。Proto显示连接使用的协议;RefCnt表示连接到本套接口上的进程号;Types显示套接口的类型;State显示套接口当前的状态;Path表示连接到套接口的其它进程使用的路径名。 事实上,netstat是若干个工具的汇总。 ◆ 显示路由表 在随- r标记一起调用n e t s t a t时,将显示内核路由表,就像我们利用r o u t e命令一样。产生的输出如下: [root@machine1 /]$ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 210.34.6.0 0.0.0.0 255.255.255.128 U 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 210.34.6.2 0.0.0.0 UG 0 0 0 eth0 - n 选项令netstat以点分四段式的形式输出IP地址,而不是象征性的主机名和网络名。如果想避免通过网络查找地址(比如避开DNS或NIS服务器),这一点是特别有用的。 netstat输出结果中,第二列展示的是路由条目所指的网关,如果没有使用网关,就会出现一个星号(*)或者0.0.0.0;第三列展示路由的概述,在为具体的I P地址找出最恰当的路由时,内核将查看路由表内的所有条目,在对找到的路由与目标路由比较之前,将对I P地址和genmask进行按位“与”计算;第四列显示了不同的标记,这些标记的说明如下: ■ G 路由将采用网关。 ■ U 准备使用的接口处于“活动”状态。 ■ H 通过该路由,只能抵达一台主机。 ■ D 如果路由表的条目是由ICMP重定向消息生成的,就会设置这个标记。 ■ M 如果路由表条目已被ICMP重定向消息修改,就会设置这个标记。 netstat输出结果的Iface显示该连接所用的物理网卡,如eth0表示用第一张,eth1表示用第二张。 ◆ 显示接口特性 在随- i标记一起调用时, netstat将显示网络接口的当前配置特性。除此以外,如果调用时还带上-a选项,它还将输出内核中所有接口,并不只是当前配置的接口。netstat-i的输出结果是这样的: [root@machine1 /]$ netstat -i Kernel Interface table Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg eth0 1500 0 787165 0 0 1 51655 0 0 0 BRU eth1 1500 0 520811 0 0 0 1986 0 0 0 BRU lo 3924 0 1943 0 0 0 43 0 0 0 LRU MTU和Met字段表示的是接口的MTU和度量值值;RX和TX这两列表示的是已经准确无误地收发了多少数据包( RX - OK / TX - OK)、产生了多少错误( RX-ERR/TX-ERR)、丢弃了多少包(RX-DRP/TX-DRP),由于误差而遗失了多少包(RX-OVR/TX-OVR);最后一列展示的是为这个接口设置的标记,在利用ifconfig显示接口配置时,这些标记都采用一个字母。它们的说明如下: ■ B 已经设置了一个广播地址。 ■ L 该接口是一个回送设备。 ■ M 接收所有数据包(混乱模式)。 ■ N 避免跟踪。 ■ O 在该接口上,禁用A R P。 ■ P 这是一个点到点链接。 ■ R 接口正在运行。 ■ U 接口处于“活动”状态。 ◆ 显示链接 netstat支持用于显示活动或被动套接字的选项集。选项- t、- u、- w和- x分别表示TCP、UDP、RAW和UNIX套接字连接。如果你另外还提供了一个- a标记,还会显示出等待连接(也就是说处于监听模式)的套接字。这样就可以得到一份服务器清单,当前所有运行于系统中的所有服务器都会列入其中。 调用netstat -ta时,输出结果如下: [root@machine1 /]$ netstat -ta Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 2 210.34.6.89:telnet 210.34.6.96:2873 ESTABLISHED tcp 0 0 210.34.6.89:1165 210.34.6.84:netbios-ssn ESTABLISHED tcp 0 0 localhost.localdom:9001 localhost.localdom:1162 ESTABLISHED tcp 0 0 localhost.localdom:1162 localhost.localdom:9001 ESTABLISHED tcp 0 0 *:9001 *:* LISTEN tcp 0 0 *:6000 *:* LISTEN tcp 0 0 *:socks *:* LISTEN tcp 0 80 210.34.6.89:1161 210.34.6.10:netbios-ssn CLOSE 上面的输出表明部分服务器处于等待接入连接状态。利用- a选项的话,netstat还会显示出所有的套接字。注意根据端口号,可以判断出一条连接是否是外出连接。对呼叫方主机来说,列出的端口号应该一直是一个整数,而对众所周知服务(well known service)端口正在使用中的被呼叫方来说,netstat采用的则是取自/etc/services文件的象征性服务名。
2023-08-19 11:40:192

Swift 安装protobuf

1、官方项目地址: https://github.com/apple/swift-protobuf 2、拉取项目到本地 3、进入项目本地路径,查看版本 4、根据项目需要,选择版本编译 如:1.5.0 5、构建项目 6、构建完成之后会生成一个 protoc-gen-swift 执行路径:swift-protobuf/.build/release/protoc-gen-swift7、把protoc-gen-swift文件直接拷贝到/usr/local/bin目录下 8、swift版本的protobuf已安装完成,现在可以来测试使用 准备一个proto文件(Book.proto) 9、生成swift文件 10、把生成的Book.swift文件拖入到项目中就可以使用了
2023-08-19 11:40:271

wireshark内置支持protobuf吗

只要你装了WINPCAP 就可以自己编程抓包,或使用wireshark抓包了。但是无线网卡好像无法通过winpcap抓包,具体如何实现无线网卡抓包,还没有研究过。6930p自带网卡绝对可以抓包,我开发网络抓包程序就是通过笔记本实现的,网卡也是我的三星笔记本自带的。
2023-08-19 11:40:362

无 proto文件即不知道服务端的.proto文件格式 客户端能不能解析成普通易懂的string

Protocol Buffers的是一个高效且可扩展的格式结构化数据编码的一种方式。谷歌使用了Protocol Buffers的几乎所有它的内部RPC协议和文件格式使用protobuf传输的好处有:二进制传输,安全、数据量小.proto文件中我们服务器定义需要传输的数据,及数据类型等。而传输的时候则是使用了通过官方工具生成的具体为.java的消息体
2023-08-19 11:40:441

Protobuf 数据格式

简单来说, Protocol Buffers 是一种和语言平台都没关的数据交换格式。 关于 Protobuf 在iOS下的使用请看上篇文章 iOS 的 Protocol Buffer 简单使用 Protobuf 序列化后的二进制数据消息非常的紧凑,这得益于 Protobuf 所采用的 Varint Varint 是一种紧凑的表示数字的方法,它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数。这能减少用来表示数组的字节数。 比如对于 int32 类型的数字,一般需要4个 byte 来标识。但是采用 Varint,对于很小的 int32 类型的数字,也能用1个 byte 来标识。如果数字很大,也就需要5个 byte 来表示了。但是,一般情况下很少会出现数字都是大数的情况下。 正常情况下,每个 byte 的8个 bit 位都用于存储数据用,而在 Varint 中,每个 byte 的最高位的 bit 有着特殊的含义,如果该位为1,表示后续的 byte 也是该数据的一部分;如果该位为0,则结束。其他的7个 bit 位都用来表示数据。因此小于127的 int32 数字都可以用一个 byte 表示,而大于等于 128 的数字:如128,则会用两个字节表示: 1000 0000 0000 0001 (采用的是小端模式),311则表示: 1011 0111 0000 0010 下图演示了 Protobuf 如果通过2个 byte 解析出 128。Protobuf 字节序采用的是 little-endian(小端模式) int32 数据类型能表示负数,负数的最高位为1,如果负数也使用这种方式表示会出现一个问题,int32 总是需要5个字节,int64 总是需要10个字节。所以 Protobuf 定义了另外一种类型 sint32, sint64,采用 ZigZag 编码,所有的负数都使用正数表示,计算方式为: Protobuf 消息是一系列的键值对组成。消息的二进制版本仅使用 field 数字当作 key,不同 field 的属性和类型只能通过消息类型的定义 (即 .proto 文件) 在解码端确定。如果消息中不存在该 field,那么序列化后的 Message Buffer 中也不会有该 field,这些特性都有助于节约消息本身的大小。 Key 用来标识具体的 field,在解包的时候,Protobuf 根据 key 就能知道相应的 Value 对应于消息中的哪一个field,数据类型是哪个类型。 Key 的定义如下: Key 由两部分组成:第一个部分是 field_number,比如上篇文章定义的消息 FooSimpleMessage 中的 msgId 属性的 field_number 为1;第二部分为 wire_type,表示 Value 的传输类型 表1. Wire Type 在之前的例子中,msgId 采用的数据类型为 int32,因此对应的 wire_type 为0,所以对应的 tag 为 FooSimpleMessage 的 msgContent,field_number 为2,wire_type 为2,所以对应的 tag 为 对应 Length-delimited 的 wire type,后面紧跟着的 Varint 类型表示数据的字节数。所以 msgContent 的 key 后面紧跟着的 0x1a 表示后面的数据长度为10个字节,"A protobuf message content" 的 ASCII 值即为: 0x41 0x20 0x70 0x72 0x6f 0x74 0x6f 0x62 0x75 0x66 0x20 0x6d 0x65 0x73 0x73 0x61 0x67 0x65 0x20 0x63 0x6f 0x6e 0x74 0x65 0x6e 0x74 在 Demo 里面定义的 msg 对象,其序列化后的数据的十六进制表示应该为 0801121a 41207072 6f746f62 7566206d 65737361 67652063 6f6e7465 6e74 运行demo,打印一下结果和猜想的一样: 参考地址: Protocol-buffers Encoding
2023-08-19 11:40:521

原始汉语(Proto-Chinese)从原始汉藏语分出以后,由SOV到SVO的语序变化是怎么出现的?

殷商的更SVO,而周人的更SOV。殷商的语序来源,暂时不太清楚。而周人因为更加靠近藏语、一些羌族人的语言,所以在几百年的语言接触中,语法受到影响。一般,两种语言接触融合,会保留强势语言的词汇,而保留弱势语言的语法。这种语序作为语法的一部分被周人所接受。后来周人又重新入住中原,推翻了殷商人,将他们的语言,确切的说,是姬姓王室,带回了中原。但是,随后他们又雅言化了,又变成以SVO为主,这需要一定是历时材料的梳理。这一点,先秦文献,可以看出一点端倪。比如,诗经中不同的国家的用词有所不同。安大简出土的诗经中,只有姬姓诸侯国,会采用"言",作为第一人称代词。(当然,也有人认为安大简是伪造的。所以材料还是存疑)如果能够继续在各种文献中找到一批这样的现象,上古汉语的两层基本可以坐实。在这个框架下,可以进一步弄清楚题主的问题。
2023-08-19 11:41:064

python grpc如何给proto文件中map类型的变量赋值?

改完之后,你可以选择project->clean,clean后你项目的R.java文件就会重新生成,所有的资源ID会重新分配,这样子你所修改的资源才能被Android真正识别,有时这个操作不是必要的,但是如果出现你修改了资源后,你的项目中出现了一些问题,那么执行Clean是一个必须的选择,这些资源包括drawable下的图片,布局里id的修改,values下资源的修改,你可以着手试一下 Good luck
2023-08-19 11:41:301

ProtocolBuffer浅析

ProtocolBuffer是google 定义的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。ProtocolBuffer类似于xml、json,不过它更小、更快、也更简单。 目前使用最广泛的数据传输协议为JSON,JSON是一种轻量级的数据交换格式而且层次和结构比较简单和清晰,这里主要对比一下Protocol Buffer和JSON的对比,给出优势和劣势: 优势 劣势 实际数据对比 Protocol Buffer的使用流程总体可以分为三步,如下图所示: google推荐在Android项目中使用lite版,lite版本生成的java文件更加轻量,其配置如下: 首先创建一个.proto文件,并且在文件中声明如下内容: 在整个proto文件中数据类型分为基本类型和结构类型,其中结构类型主要为: 下面分别介绍一下不同结构的作用及规定: message表示一个结构,类似于java中类,一个proto文件中可以声明多个message结构: message可以引用不同proto文件中的message,只要在proto文件中的最上面声明import即可,如下所示: enum使用很简单,直接在message中声明enum结构体并且将属性声明为对应的enum即可: 在proto3中,enum第一个值必须为0,主要是为了和基础类型的默认值保持一致 map是proto3新加的,使用也很简单: 如下 repeated修饰的属性类似于jsonArray,也类似于java中的List,该修饰符在格式正确的消息中可以重复任意次(包括0次) 日常开发过程中,由于需求的变更,往往需要增加字段,这就涉及到字段的扩充,字段扩充需要达到一个目的: 兼容 所以Protocol Buffer在字段扩充中定义了如下规则: 只要记住上述规则,就能完成字段扩充且老版本也能兼容 Protocol Buffer 更快更小的主要原因如下: 上面这个例子中,在序列化时,"name" 、"count"的key值不会参与,由编号1、2代替,这样在反序列化的时候直接通过编号找到对应的key就可以。需要注意的是编号一旦确定就不可以更改,服务端和客户端通过proto通信的时候需要提前定义号数据格式。 其中Length不一定有,依据Tag确定,例如int类型的数据就只有Tag-Value,string类型的数据就必须是Tag-Length-Value。 Protocol Buffer定义了如下的数据类型,其中部分数据类型已经不再使用: 上面已经介绍了Protocol Buffer的数据结构及Tag的类型,但是Tag块并不是只表示数据类型,其中数据编号也在Tag块中,Tag的生成规则如下: 其中Tag块的后3位表示数据类型,其他位表示数据编号 Java中整数类型的长度都是确定的,如int类型的长度为4个字节,可表示的整数范围为-2 31——2 31-1,但是实际开发中用到的数字均比较小,会造成字节浪费,可变长度编码就能很好的解决这个问题,可变长度编码规则如下: 举个例子: 其中第一个字节由于最高位为1,则后面的字节也是前面的数据的一部分,第二个字节最高位为0,则表示数据计算终止,由于Protocol Buffer是低位在前,整体的转换过程如下: 10000001 00000011 ——> 00000110000001 表示的10进制数为:2^0 + 2^7 + 2^8 = 385 通过上面的例子可以知道一个字节表示的数的范围0-128,上面介绍的Tag生成算法中由于后3位表示数据类型,所以Tag中1-15编号只占用1个字节,所以确保编号中1-15为常用的,减少数据大小。 可变长度编码唯一的缺点就是当数很大的时候int32需要占用5个字节,但是从统计学角度来说,一般不会有这么大的数. 上面介绍了Protocol Buffer的原理,现在通过实例来展示分析过程,我们定义的proto文件如下: 其序列化后的字节数据如下: 前面介绍过Protocol Buffer的 数据结构为TLV,其中L不是必须的,根据T的类型来确定 先看下第一个字节: 这里字节最高位为0,所以该Tag就用这一个字节表示,其中后3位表示类型,前面表示字段编号,所以: 这里字节最高位为0,所以该Tag就用这一个字节表示,其中后3位表示类型,前面表示字段编号,所以: file_num = 0001 = 1 type = 010 = 2 上面介绍过type=2,则后面有Length,按照可变长度编码规则,知道表示长度的字节为: 所以Length=4,则value的长度是4个字节,直接取出后面4个字节: 这4个字节对应的就是test 再看下一组: 由上面的Tag知道: file_num=2 type=0 前面介绍过type=0,后面没有Length,直接就是value, value=1,通过上面的解析可以知道 上面介绍了Protocol Buffer的原理,解释了为什么Protocol Buffer更快,更小,这里再总结一下: 参考资料: proto3官网指南: https://developers.google.com/protocol-buffers/docs/proto3 protobuf-gradle-plugin: https://github.com/google/protobuf-gradle-plugin 博客: https://juejin.im/post/5dcbf630e51d451bfe5bb21b
2023-08-19 11:41:381

File does not reside within any path specified using --proto_path

使用--proto_path=. --swift_out=. ***.proto 生成swift文件时 报错: File does not reside within any path specified using --proto_path (or -I). You must specify a --proto_path which encompasses this file. Note that the proto_path must be an exact prefix of the .proto file names -- protoc is too dumb to figure out when two paths (e.g. absolute and relative) are equivalent (it"s harder than you think). 给出明确的路径就可以了,如: protoc --proto_path=/Users/Mac/Documents --swift_out=/Users/Mac/desktop ***.proto
2023-08-19 11:41:461

protobuffer 怎么输出

在网上查了一下,虽然有很多文章介绍Protocol Buffer,但是实际使用起来,还是会遇到很多问题,所以我想应该有一个指南一样的东西,让新手很快就能使用它。Protocol Buffer简写为Protobuf,是Google开发的一种储存数据的方式,功能与XML一样,但更方便,数据量更小,速度更快,在序列化和反序列化的时候使用,有很大的优势。比如,网络游戏的通讯协议编写。更重要的是,它是一个开源项目。由于Protobuf不能生成C#代码,所以就要用到另外一个开源项目protobuf-net,用法是,在命令行用protoc.exe依据你自己定义的.proto文件,来生成.cpp文件用protobuf-net的protogen.exe来生成.cs文件,可以写一个批处理,如下:protoc -I=. --cpp_out=. Net.proto //在当前目录下,以cpp方式编译Net.protoprotogen -i:Net.proto -o:Net.cs //在当前目录下,用Net.proto生成Net.cs其实两句功能是一样,只是分别生成了Net.proto的cpp文件和cs文件,这样就可以在两种语言编写的应用程序间通信了。
2023-08-19 11:42:061

了解一下ProtoBuf

我们在进行网络通信调用的时候,总是需要将内存的数据块经过序列化,转换成为一种可以通过网络流进行传输的格式。而这种格式在经过了传输之后再经过序列化,能还原成我们预想中的数据结构。 那么我们对于这种用于中间网络传输的数据格式就有一定的要求。首先它可以准确地描述数据内容,在此基础上我们则希望它尽量的小。 最开始流行起来的是XML,可扩展标记语言。由于它可以用来标记数据、定义数据类型,所以用户可以自己定义数据自己的语言,从而让对不同的数据结构化成统一的格式称为了可能。 而另外一个我们熟知的则是JSON(JavaScript Object Notation, JS 对象简谱)。尽管JSON中缺少了XML中的标签属性等描述方式,但是足够简介和清晰的层次结构使得其成为了必XML更受欢迎的数据交换格式。 同一份数据显然JSON的数据量比XML所使用的空间更少。那么空间省略在哪里呢?一方面是json使用更简单的字符来定义数据间的关联关系;另一方面是JSON减少了对数据类型的描述。但是丢少的数据类型再哪里呢? 以Java中的 OpenFeign 举例,JSON中缺少的类型定义被定义道程序中的接口中了。当进行序列化与反序列化时,JSON格式并不记录数据的类型,具体的数据类型在序列化方与反序列化方通过事先约定的接口来进行定义。这样就减少了信息传输过程中的信息量,从而让数据得以压缩。 但是JSON由于没有定义数据类型,所以在传输的过程中实际上就都是文本流,那么这种方法还可以进一步压缩吗? 结合上文的讨论,我们先说结论:方法是有的,并写当前的实现方式是ProtoBuf。但在此之前我们先来了解一下ProtoBuf。 我们可以先看看官方给出的定义与描述: 同样的,ProtoBuf也是一种支持序列化反序列化的方法,并且他具有很多优点: 实际上,ProtoBuf提供了一种通用的数据描述方式,这种定义数据的方式是通用的,就如同JSON或者XML一样。 接下来我们来来回答本节一开始的问题,针对JSON来说,ProtoBuf是如何将体积变得更小的呢?答案很简单,就是为数据序列化反序列化提供更多的先验知识。 本文暂不过度深入ProtoBuf原理,但是可以通过一张图来进行简要说明(): ProtoBuf中的数据是按顺序进行排列,而整体的结构为若干个field,每一个field中由 Tag-[Length]-Value 组成。Length是可选的,而是否存在Length是通过Tag的类型来决定的。也就是说如果是指定的类型,比如int64,那我们就可以知道Value的长度,也就不用在依靠Length来对其空间进行描述(redis中的压缩列表也是这个思想)。 那么field应该对应的是什么字段呢?这个则是在序列化与反序列化时在ProtoBuf的服务端与客户端之间进行预先定义的。而因为提前定义了field的类型、排序,所以field本身可以不用对字段名、字段位置进行描述,只需要根据字段类型选用合适的二进制序列化方法,将字段本身的value值进行序列化传输即可。 稍微总结一下: ProtoBuf通过对传输字段的名称、顺序进行预定义,从而在传输结构中只需要顺序的记录每个字段的类型标签和二进制值。 尽管上文和官方中都是以XML或者JSON来对ProtoBuf进行对比。但是因为ProtoBuf本身就是二进制序列化方式,所以从压缩比上比较感觉有点欺负人。 对应的在Java中二进制常用的序列化器有Kryo和Hessian。但事实上,由于Kryo和Hessian中都需要对Java类名和字段信息进行存储。而ProtoBuf则只有Tag-Length-Value的数据对,且Value更是有针对性的特殊编码,所以空间占用小的很多。 Kryo是专门针对Java进行优化了的。所以在使用的便捷性上来说Kryo则更加方便。但ProtoBuf是跨平台的,且由于进行了字段的顺序定义,所以似的ProtoBuf定义后的接口是可以向前兼容的(只向后追加字段),而这种优势是Kryo所没有的。 ProtoBuf是跨语言的,使用ProtoBuf的第一步是先定一个 proto 文件 ,而由于ProtoBuf 2和3语言版本的不同,其定义格式会有所不同,具体的细节还是得参考官方文档:https://developers.google.cn/protocol-buffers/docs/proto3 对于ProtoBuf 3 的定义文档我们可以按如下方法定义: 其中message关键字是定义的文件名,而 string、int32则是预定的字段类型,repeated则是描述字段为可重复任意多次的字段。 ProtoBuf通过这种形式的文件定义了传输信息的文件结构。 但是之前小节中我们知道了ProtoBuf是通过 Tag-[Length]-Value 组成的数据组来进行信息传输的,那么proto文件中定义的内容如何转换为实际传输的对象呢? ProtoBuf的做法是,为每一种语言提供一个生成器protoc。通过使用protoc则可以根据.proto文件生成为一组java文件。对应的官方语法演示样例为: 官方的生成参考为:https://developers.google.com/protocol-buffers/docs/reference/java-generated 生成后的java文件将提供对应的实体以及数据的构造方法等文件,从而支持后续的使用。 需要注意的是,ProtoBuf是本质上是序列化方法,具体是通过Spring Cloud 的OpenFeign进行接口调用,还是通过grpc进行接口调用,都是可以的。 本文对ProtoBuff进行了概念的整理,并没有对每个细节都进行深入的梳理,可以当作概念科普来进行阅读。
2023-08-19 11:42:271