乐趣区

自定义报头协议

自定义报头协议

在学习过计算机网络的课程, 我们知道刚开始计算机都是单独脱机工作的, 没有联网的情况下计算机的信息共享能力、运算能力都非常有限, 后来诞生了计算机网络. 有了就是那几网络, 计算机 A 的信息和数据可以通过网络传递到计算机 B, 同样计算机 A 可以获取到来自计算机 B 的数据. 但是不同计算机之间交换数据的时候就要通过网络来传输了. 传输的过程中需要不同的计算机都遵循一定的规则来组装数据、传递信息, 那么这样的规则就叫做协议.

1. 协议

计算机网络中有非常多协议, 这些协议位于 OSI 的不同层中, 比如 TCP/IP、UDP、SMTP、FTP 等. 协议之所以称为协议, 是因为它具有约束效应, 信息在端到端的传输过程中, 同等层次之间通过使用同样的协议规则, 这样发送方在该层次按照协议约定处理数据, 接收方在该层次按照协议约定解析数据. 成对存在.


2. 自定义协议

在日常开发的时候处于某些原因可能需要自定义报文协议. 这个协议是建立在 TCP 连接的基础上, 比如, 移动端在做 APM 的时候将功能拆分为 2 个模块, 一个是 APM 监控模块、一个为了方便可拓展单独做了一个数据上报组件, 具有动态下发上报策略的配置.

所以上报组件这里涉及到和服务端高效通信, 所以客户端和服务端约定了一套自定义的报文协议, 如下所示.

  • PACKET 整体结构
    | HEAD | META | BATCH_PAYLOAD |
  • PACKET::HEAD 结构

    | META_SIZE (2bytes unsigned int) | BATCH_COUNT (1 bytes unsigned int) | PAYLOAD_SIZE (4bytes unsigned int) | PAYLOAD_SIZE (4bytes unsigned int) | … |

  • PACKET::META 结构

    换行符分割的 JSON 字符串

    crypto(deflate(JSONnJSON…))

  • PACKET::BATCH_PAYLOAD 结构

    JSON 体里每个字段的值都是 BASE64 编码的

    crypto(deflate(JSON) | crypto(deflate(JSON) | …

其实计算机网络过程中传输的就是二进制数据, 所以拿 iOS 举例来说, 我们自定义报文协议的目的就是按照协议的约定, 自定义组装好一个 NSData 的数据, 报文里面的头规定了各种信息的组装格式.

  • HEAD 里面需要携带 3 个信息. 信息 1:meta 的 size 信息, 而且协议规定了必须使用 2byte 的 unsigned int 数据类型. 信息 2: payload 报文的个数, 必须使用 1byte 的 unsigned int 数据类型. 信息 3: 每个报文的大小, 必须使用 4byte 的 unsigned int 数据类型.
  • META 里面需要携带 1 个信息. 将多条元数据用 “n” 换行符拼接, 另外拼接完的整体数据先压缩再加密
  • PAYLOAD 里面将每条数据先压缩, 然后整体再加密

所以核心就上面的 3 点, 一点都不难, 只不过第一次做的时候可能会踩坑. 列觉如下

  • 协议明确规定了该采用什么样的数据类型, 另外数据大小做了明确限制, 如果你不这么做, 服务端按照字节长度去解析数据就会出错, 相应的客户端接口的返回结果就是失败. 自讨苦吃
  • 设计到数据的处理, 就应该注意字节序的问题, 比如 iOS 采用的小端序, 网络规定数据传输使用大端序, 假如你不知道这个问题, 那么你很可能接口调用失败, 所以你需要将你的数据转换为大端序的数据, 关于大小端序的问题可以查看我的这篇文章

Objective-C 语言中处理 unsigned int 的数据, 所以你需要直接操作 unsign short 到 NSData, NSData 的接口很方便, [NSData dataWithBytes:&metaLength length:sizeof(metaLength)]] 就可以处理成 2byte 的 unsigned int 的数据

退出移动版