使用脚本收发 protobuf 协议数据

这篇具有很好参考价值的文章主要介绍了使用脚本收发 protobuf 协议数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题背景

最近做了一个 ipv6 相关的功能,发现使用 getifaddrs 获取的本地 ipv6 地址有可能不是真实的网络 ipv6 地址:

使用脚本收发 protobuf 协议数据

例如上图中通过 getifaddrs 获得了多个本地 ipv6 地址,其中 <fe80> 开头的已知是本地 ipv6 地址,被排除;还有 <2408> 这种,其实也是 "假 ipv6" 地址,对应的设备并不能访问 ipv6 网络。

对于这种假 v6 地址,无法通过遍历的方式进行枚举排除,而一旦将 v4 网络环境错认为是 v6 环境,对后面的网络操作影响比较大。需要引入一种准确判断当前网络是否有 ipv6 访问能力的方法,为此 server 端同学专门给了一个判断接口。

probe_v6_addr

出于安全考虑,这里只列出接口名称部分:

http://xxx.xxxxxxxxxx.xxxxxxx.xxxxx.xxx/xxx/probe_v6_addr

访问这个接口有两种返回,当不存在 v6 网络环境时:

no v6 addr

当存在时,返回本机的 ipv6 地址:

$ curl -s http://xxx.xxxxxxxxxx.xxxxxxx.xxxxx.xxx/xxx/probe_v6_addr
+
%240e:304:8183:2bcc:c16d:22d0:74ba:23e??-
'2408:832e:c272:b36e:55bc:554a:8952:553e,
&240e:3a0:7005:6ae2:d05a:754a:c21b:6c35??+
%240e:310:915:d939:9041:c01c:82db:a043??-
'2408:832e:c271:3851:6926:e953:e741:b1a3??+
%240e:378:1e0c:db62:7088:a216:87c:4ccd??OP46C3:/

虽然有部分二进制信息干扰,但是 ipv6 地址部分还是看得比较清楚的。返回的地址和 ifconfig 的结果可以相互印证:

$ ifconfig | grep inet6
          inet6 addr: fe80::fc8e:84ff:fec0:1534/64 Scope: Link
          inet6 addr: 240e:505:7e01:2994:f43c:5fc9:609e:5de6/64 Scope: Global
          inet6 addr: fe80::f43c:5fc9:609e:5de6/64 Scope: Link
          inet6 addr: fe80::8fd0:cd9e:52cd:5bc3/64 Scope: Link
          inet6 addr: 2409:8100:7b00:5781:a4a8:71ce:b11:3c5e/64 Scope: Global
          inet6 addr: fe80::a4a8:71ce:b11:3c5e/64 Scope: Link
          inet6 addr: ::1/128 Scope: Host
          inet6 addr: fe80::29f8:41f:7564:501d/64 Scope: Link
          inet6 addr: 240e:404:7e01:5d77:29f8:41f:7564:501d/64 Scope: Global
          inet6 addr: fe80::3d14:7716:4771:88fa/64 Scope: Link
          inet6 addr: 240e:304:8183:2bcc:c16d:22d0:74ba:23e/64 Scope: Global
          inet6 addr: 240e:304:8183:2bcc:d8c5:dce4:a89c:8a88/64 Scope: Global

其中 ipv6 地址240e:304:8183:2bcc:c16d:22d0:74ba:23e/64在两边都存在。

protobuf

上面的接口确实是基于二进制数据的协议,虽然是私有协议,但是采用了 protobuf 来进行规范,在提高性能的同时,也保留了一定的通用性。

但是这样一来,往常惯用的 curl + shell 大法要失灵了,给测试和验证工作带来了不小的麻烦。

不过好在有 proto 文件,生成一段解析的 c++ 代码也不是不可能:

> cat msg.proto
message ProbeIpv6Request {
    string xxxxx     = 1;
    string xxxx      = 2;
    string xxxxxxxx  = 3;
    string xxxxxxx   = 4;
}

message V6AddrType {
    string addrV6 = 1;
    uint32 portV6 = 2;
}

message ProbeIpv6Response {
    string              xxxxx    = 1;
    V6AddrType          selfAddr = 2;
    repeated V6AddrType brosAddr = 3;
}

这个 proto 文件揭示了两点:

  • 该接口也是有请求数据的:ProbeIpv6Request,不过可以省略
  • 该接口的响应 ProbeIpv6Response 主要包含两部分:
    • selfAddr 是设备自己的地址,有且只有一个
    • brosAddr 是设备的广播地址,可能存在多个 (repeated)
    • 地址都是由一个字符串地址和一个整型端口组成

如果使用 protoc 程序根据 msg.proto 生成 c++ 代码,再写程序解析数据,就用不着写这篇文章了。毕竟那种方式太牛刀杀鸡了,下面演示一种使用 shell 脚本就能搞定 protobuf 协议的新方法。

pbjs

在介绍新方法之前,先介绍本文的主角 pbjs。首先是在 mac 上的安装:

brew install node
brew install npm
npm install -g protobufjs
npm install -g pbjs

pbjs 是 nodejs 提供的,用来将 protobuf 二进制数据转换为 json,所以需要先安装 nodejs、npm 环境,linux 上的安装大同小异,此处不再赘述。

执行成功后验证 pbjs 是否安装:

> pbjs
Usage: pbjs [options] <schema_path>

Options:
  -V, --version        output the version number
  --es5 <js_path>      Generate ES5 JavaScript code
  --es6 <js_path>      Generate ES6 JavaScript code
  --ts <ts_path>       Generate TypeScript code
  --decode <msg_type>  Decode standard input to JSON
  --encode <msg_type>  Encode standard input to JSON
  -h, --help           output usage information
> which pbjs
/Users/yunhai01/tools/node-v14.17.0-darwin-x64/bin/pbjs
> ls -lh /Users/yunhai01/tools/node-v14.17.0-darwin-x64/bin/pbjs
lrwxr-xr-x  1 yunhai01  staff    31B Apr 16 18:26 /Users/yunhai01/tools/node-v14.17.0-darwin-x64/bin/pbjs -> ../lib/node_modules/pbjs/cli.js

看起来这就是一个 node module 的软链接。

pbjs 的功能有很多,help 信息中已经罗列出来了,例如生成 js 代码 (--es5/--es6),生成 ts 代码 (--ts),不过最让我感兴趣的还是 --decode,意思是可以将数据解析为 json,下面用上一节的二进制数据做个练手,假设数据已经保存在名为 response.bin 的文件:

> pbjs msg.proto --decode ProbeIpv6Response < response.bin
{
  "selfAddr": {
    "addrV6": "240e:304:8183:2bcc:c16d:22d0:74ba:23e",
    "portV6": 47832
  },
  "brosAddr": [
    {
      "addrV6": "240e:333:6b00:b00e:38db:2815:306b:3d9b",
      "portV6": 18947
    },
    {
      "addrV6": "240e:333:1707:ca6f:24d3:61ae:86cf:a6fa",
      "portV6": 18112
    },
    {
      "addrV6": "2409:8a38:9002:70b3:19a3:66a3:d778:65cc",
      "portV6": 18780
    },
    {
      "addrV6": "2408:8266:700:1a62:8ad0:4097:9220:577b",
      "portV6": 18595
    },
    {
      "addrV6": "240e:3a0:9001:4013:99c0:11c4:7d3b:e8e5",
      "portV6": 18319
    }
  ]
}

哈哈,果然成功,过程异常丝滑!

jq

有了 json 数据就好办了,下面上 jq 提取设备 IP,假设已经将数据保存在了 response.json 文件中:

> jq -r '.selfAddr.addrV6'  probe_v6.json
240e:304:8183:2bcc:c16d:22d0:74ba:23e

和之前猜测的 IP 地址结果一致。

结语

pbjs 不光可以用来解析响应,也可以用来构造 protobuf 格式的请求,主要就是依赖它的 --encode 参数:

pbjs msg.proto --encode ProbeIpv6Request < request.json > request.bin

注意 --decode/--encode 一次只能处理一个消息类型,而协议文件中可能包括多个,所以需要为它指定要处理的消息名,之前使用的是 ProbeIpv6Response 消息,这里改为 ProbeIpv6Request 消息。

关于 request.json 文件,简单的可以直接手动构造,复杂的可以借助 jq --arg 动态生成,这方面详细的信息可以参考我之前写的这几篇文章:《用 shell 脚本做 tcp 协议模拟》、《使用 shell 脚本自动申请进京证 (六环外) 》。

至此 protobuf 二进制数据也不再是脚本不可触控的区域,有这方面接口测试需求的同学们快用起来吧 ~

后记

使用基于 pbjs 的脚本在 android 设备上验证上述接口后,能正确返回结果,并且发现了几个小问题,为后面写 c++ 代码接入铺平了道路,比起编译 sdk 再打 apk 包验证,成本实在是低太多了,pbjs 确确实实提升了我的效率。

参考

[1]. Protocol Buffers for JavaScript

[2]. 工作笔记:protobufjs使用教程,支持proto文件打包成typescript或javascript脚本

 文章来源地址https://www.toymoban.com/news/detail-472952.html

到了这里,关于使用脚本收发 protobuf 协议数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 入门小白:STM32hal库实现ESP8266与手机通信(不定长数据收发和ESP8266使用的一些问题)

    目录 前言 一、stm32cubeMX的串口配置 二、空闲中断+dma接收 三、ESP8266.c和ESP8266.h ESP8266.h ESP8266.c 注意事项 四、与手机通信例程 步骤:  例程代码main.c 运行结果 五、相关问题 总结 相关的app和源码         前提: 1.掌握串口通信和ESP8266的使用方法 串口通信:单片机串口通信

    2024年02月07日
    浏览(67)
  • 入门stm32:STM32hal库实现ESP8266与手机通信(不定长数据收发和ESP8266使用的一些问题)

    目录 前言 一、stm32cubeMX的串口配置 二、空闲中断+dma接收 三、ESP8266.c和ESP8266.h ESP8266.h ESP8266.c 注意事项 四、与手机通信例程 步骤:  例程代码main.c 运行结果 五、相关问题 总结 相关的app和源码         前提: 1.掌握串口通信和ESP8266的使用方法 串口通信:单片机串口通信

    2024年02月04日
    浏览(94)
  • 树莓派4B与智能涡轮流量计通过RS485(modbus RTU协议)收发数据(二)(Hyperledger Fabric环境中上传数据)

    上一篇博客配置好了树莓派端的串口通信,这次在加入涡轮流量计之前也先用PC端模拟树莓派测试一下该仪表是否能正常工作。 流量计说明书如下:  并且在设备上电时以(9600,8n1格式)自动发送四个字节: 返码格式:站地址(1字节)+波特率(2字节)+格式(1字节) 8n1格式

    2023年04月21日
    浏览(55)
  • 【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题

    目录 一、优化思路 二、缓存库存与订单 1、库存缓存的redis数据结构 2、订单信息缓存的redis数据结构 三、整体流程 四、lua脚本确保权限校验操作的原子性 【Redis】电商项目秒杀问题之超卖问题与一人一单问题_1373i的博客-CSDN博客 https://blog.csdn.net/qq_61903414/article/details/1305689

    2024年02月05日
    浏览(48)
  • APP爬虫之-Protobuf协议逆向解析

    在做APP抓取时,会发现有的APP Response回来的数据有“加密”。不知道返回的内容是什么。 如下: 如上,内容不是明文的,没办法解析数据。APP常见的对数据加密有三种情况:第一种是,用诸如AES这类加密算法对数据加密,然后在APP里用key进行解密,这类的数据解密的难度不

    2024年02月10日
    浏览(38)
  • 使用脚本,直接修改注册表的值---设置win10背景色(保护色)

    目录 ■修改注册表(手动) ■修改注册表(脚本化) ・修改 ・恢复 ■其他(注册表图片) === 前言,媳妇上班,不会修改win10系统背景色(她想弄成保护色),提供个脚本,一键修改。 └window ⇒207 232 204 └Window ⇒caeace ・修改 新建一个xxx.reg文件,把下面内容复制进去 ・恢

    2024年02月12日
    浏览(48)
  • vue3项目使用WebSocket 传输 Protobuf 格式的数据

    前端和后端数据传输常用数据格式: JSON(JavaScript Object Notation):与 HTTP 协议和 REST API 配合使用时,JSON 数据是最常用的数据格式之一。对于 WebSocket,JSON 数据同样适用。客户端可以将消息转换为 JSON 对象,并将其发送到服务器进行处理,在服务器上生成响应并返回给客户端

    2024年02月10日
    浏览(53)
  • rpc、gRPC快速入门,python调用,protobuf协议

    远程过程调用协议RPC (Remote Procedure Call Protocol) RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据 举例:在 a服务内

    2024年02月13日
    浏览(56)
  • STM32使用HAL库,串口收发一段时间后出错问题及解决

    当STM32使用HAL库进行开发时,偶尔会遇到串口收发数据量大时,会出现问题。比如同时串口同时收发,一段时间后就只能发送,接收不工作。或是只接收,但数据量大时也不工作。下面对这些问题和其解决办法进行整理。 当数据量过大且传输频率快时,串口可能会因为溢出,

    2024年02月16日
    浏览(41)
  • FPGA-结合协议时序实现UART收发器(一):UART协议、架构规划、框图

    记录FPGA的UART学习笔记,以及一些细节处理,主要参考奇哥fpga学习资料。 本次UART主要采用计数器方法实现,实现uart的稳定性发送和接收功能,最后实现串口数据回环进行功能测试。 UART协议如图。 包含:空闲位、起始位、数据位、校验位、停止位、空闲位(一般没有) 对于

    2024年02月08日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包