教你如何使用 Zig 实现 Cmpp 协议
本文分享自华为云社区《华为云短信服务教你用Zig实现Cmpp协议》,作者: 张俭。
引言 &协议概述
中国网络通信集团短信网关协议(CNGP)是中国网通为实现短信业务而制定的一种通信协议,全称叫做 China Netcom Short Message Gateway Protocol,用于在 PHS 短消息网关(SMGW)和服务提供商(SP)之间、短消息网关(SMGW)和短消息网关(SMGW)之间通信。
Zig 是一种性能优异、安全性高的系统编程语言,适合用于实现底层网络协议。它提供了强大的类型系统、编译时计算和错误处理机制。
CNGP 协议基于客户端/服务端模型工作。由客户端(短信应用,如手机,应用程序等)先和短信网关(SMGW Short Message Gateway)建立起 TCP 长连接,并使用 CNGP 命令与 SMGW 进行交互,实现短信的发送和接收。在 CNGP 协议中,无需同步等待响应就可以发送下一个指令,实现者可以根据自己的需要,实现同步、异步两种消息传输模式,满足不同场景下的性能要求。
时序图
连接成功,发送短信
连接成功,从 SMGW 接收到短信
协议帧介绍
在 CNGP 协议中,每个 PDU 都包含两个部分:CNGP Header 和 CNGP Body
CNGP Header
Header 包含以下字段,大小长度都是 4 字节
Total Length:整个 PDU 的长度,包括 Header 和 Body。
Command ID:用于标识 PDU 的类型(例如,Login、Submit 等)。
Common Status:命令状态
Sequence Id:序列号,用来匹配请求和响应。
使用 Zig 实现 CNGP 协议栈里的建立连接
bound_atomic.zig:原子递增工具类,用来做 SequenceId
cngp_client.zig:这个文件包含 Cngp 的定义,该类负责与 CNGP 服务进行通信,例如建立连接、发送短信等
cngp_client_login_example.zig:示例代码
constant.zig:存放常量
protocol.zig:这个文件包含 CNGP 协议相关的定义和实现,例如协议的命令 ID、PDU 格式等。
constant.zig 存放相关 commandId
protocol.zig 协议编解码
利用原子类型实现 sequenceId 递增
实现 client 以及 login 方法
运行 Example,验证连接成功
相关开源项目
netty-codec-sms 存放各种 SMS 协议(如 cmpp、sgip、smpp)的 netty 编解码器
sms-client-java 存放各种 SMS 协议的 Java 客户端
sms-server-java 存放各种 SMS 协议的 Java 服务端
cmpp-python cmpp 协议的 python 实现
cngp-zig cmpp 协议的 python 实现
smpp-rust smpp 协议的 rust 实现
总结
本文简单对 CNGP 协议进行了介绍,并尝试用 zig 实现协议栈,但实际商用发送短信往往更加复杂,面临诸如流控、运营商对接、传输层安全等问题,可以选择华为云消息 &短信(Message & SMS)服务,华为云短信服务是华为云携手全球多家优质运营商和渠道,为企业用户提供的通信服务。企业调用 API 或使用群发助手,即可使用验证码、通知短信服务。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/5de127ace4b8d0930a79b73c9】。文章转载请联系作者。
评论