教你用 Perl 实现 Smgp 协议
引言 &协议概述
中国电信短消息网关协议(SMGP)是中国网通为实现短信业务而制定的一种通信协议,全称叫做 Short Message Gateway Protocol,用于在短消息网关(SMGW)和服务提供商(SP)之间、短消息网关(SMGW)和短消息网关(SMGW)之间通信。
Perl 是一个老牌脚本语言,在众多 Linux 系统上都会默认安装,比如在 ubuntu 的 22.04 版本的基础镜像中,甚至没有 Python,但是依然安装了 Perl,Perl 的普及度可见一斑。Perl 的 IO::Async 模块提供了一套简洁的异步 IO 编程模型。
SMGP 协议基于客户端/服务端模型工作。由客户端(短信应用,如手机,应用程序等)先和短信网关(SMGW Short Message Gateway)建立起 TCP 长连接,并使用 CNGP 命令与 SMGW 进行交互,实现短信的发送和接收。在 CNGP 协议中,无需同步等待响应就可以发送下一个指令,实现者可以根据自己的需要,实现同步、异步两种消息传输模式,满足不同场景下的性能要求。
时序图
连接成功,发送短信
连接成功,从 SMGW 接收到短信
协议帧介绍
SMGP Header
Header 包含以下字段,大小长度都是 4 字节
Packet Length:整个 PDU 的长度,包括 Header 和 Body。
Request ID:用于标识 PDU 的类型(例如,Login、Submit 等)。
Sequence Id:序列号,用来匹配请求和响应。
使用 perl 实现 SMGP 协议栈里的建立连接
Makefile.PL:用来生成 Makefile
examples:存放示例代码
smgp_client_login_example.pl:存放 Smgp 的 login 样例
lib/Smgp:包含所有的 Perl 模块文件
BoundAtomic.pm:递增工具类,用来生成 SequenceId
Client.pm:Smgp 定义,负责与 Smgp 服务进行通信,例如建立连接、发送短信等
Protocol.pm:存放 PDU,编解码等
实现 sequence_id 递增
sequence_id 是从 1 到 0x7FFFFFFF 的值
在 Perl 中定义 SMGP PDU 以及编解码函数
constant.pm 存放相关 requestId
实现 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 实现
smgp-perl smgp 协议的 perl 实现
smpp-rust smpp 协议的 rust 实现
总结
本文简单对 SMGP 协议进行了介绍,并尝试用 perl 实现协议栈,但实际商用发送短信往往更加复杂,面临诸如流控、运营商对接、传输层安全等问题,可以选择华为云消息 &短信(Message & SMS)服务通过 HTTP 协议接入,华为云短信服务是华为云携手全球多家优质运营商和渠道,为企业用户提供的通信服务。企业调用 API 或使用群发助手,即可使用验证码、通知短信服务。
文章转载自:华为云开发者联盟
评论