一、CMPP2.0協議概述
中國移動短信網關是全球最大的移動短信平台之一,其協議主要包括SMPP、CMPP、SGIP等。CMPP(China Mobile Peer to Peer)是中國移動基於TCP/IP協議棧實現的短信網關協議,CMPP2.0是其第二個版本,是目前最為普遍採用的版本。
CMPP2.0採用二進制格式進行消息傳輸,具有高效、穩定的特點。通過CMPP2.0協議,短信發送方可以將短信發送到中國移動短信網關,網關再將短信轉發到接收方的手機上。需要注意的是,CMPP2.0協議中的短信發送和接受都是異步的。
二、CMPP2.0協議結構
CMPP2.0協議報文結構主要包括消息頭、消息體和消息尾三部分。
1. 消息頭
消息頭包括以下內容:
struct cmpp3_header {
unsigned int total_length; // 消息總長度
unsigned int command_id; // 命令標識
unsigned int sequence_id; // 消息序列號
};
其中,total_length表示整個消息的長度,包括消息頭、消息體和消息尾;command_id表示消息類型;sequence_id表示消息序列號,用於標識服務器的響應。
2. 消息體
消息體中包含具體的業務數據。不同的消息類型有着不同的消息體格式。例如,CMPP_CONNECT消息中包含SP_Id、Secret等字段;CMPP_SUBMIT消息中包含短信內容、短信號碼等字段。
3. 消息尾
消息尾主要是用來填充報文,保證整個報文的長度為8的倍數,方便數據傳輸和處理。
三、CMPP2.0協議消息類型
CMPP2.0協議一共支持9種不同類型的消息,分別是:
- CMPP_CONNECT請求/響應消息:用於建立和中斷連接;
- CMPP_TERMINATE請求/響應消息:用於正常關閉與服務器的連接;
- CMPP_SUBMIT請求/響應消息:用於提交短信;
- CMPP_DELIVER請求/響應消息:用於接收短信;
- CMPP_QUERY請求/響應消息:用於查詢狀態報告;
- CMPP_CANCEL請求/響應消息:用於取消提交的短信;
- CMPP_ACTIVE_TEST請求/響應消息:用於測試連接狀態;
- CMPP_FWD請求/響應消息:用於將短信轉發到其他號碼;
- CMPP_MT_ROUTE請求/響應消息:用於短信路由管理。
四、CMPP2.0協議示例代碼
1. 建立連接
下面是建立連接的示例代碼。目前,中國移動短信網關提供IP地址為60.12.13.50的網關,可以在測試時直接使用。
# 定義IP和端口號
HOST = '60.12.13.50'
PORT = 7890
# 連接服務器
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
# 發送CMPP_CONNECT請求
connect_msg = pack('>III6s16s3sI', 39, 0x00000001, 1, '', 'user', 'pass', int(time.time()))
sock.send(connect_msg)
resp_msg = sock.recv(1024)
# 解析CMPP_CONNECT響應
total_length, command_id, status = unpack('>III', resp_msg[:12])
if command_id == 0x80000001 and status == 0:
print('Connect OK')
else:
print('Connect failed')
sock.close()
2. 提交短信
下面是提交短信的示例代碼。在代碼中,SP_id、src_id和msg_content等參數需要替換成實際的值。
# 獲取消息流水號
sequence_id = random.randint(1, 65535)
# 構造CMPP_SUBMIT消息
msg_content = '測試短信'
msg_type = 0
fee_type = ''
fee_code = ''
fixed_msg_id = 0
msg_level = 0
src_id = '1234'
dest_id = '13800138000'
dest_terminal_type = 0
service_id = ''
tp_pid = 0
tp_udhi = 0
msg_fmt = 15
msg_length = len(msg_content.encode('gbk'))
pk_total = 1
pk_number = 1
tp_udhi = 0
msg = struct.pack('>III10s4s4s3sBBI21s21sBBBBIHBBI', 156 + msg_length, 0x00000004, sequence_id, # 填充消息頭
b'source_id', b'1370000000', b'sp_code', b'', msg_level,
service_id.encode('gbk'), tp_pid, tp_udhi, msg_fmt, dest_terminal_type,
1, '', pk_total, pk_number, registered_delivery, msg_level, fee_type, fee_code,
fixed_msg_id, msg_content.encode('gbk'))
# 發送短信
sock.send(msg)
resp_msg = sock.recv(1024)
# 解析CMPP_SUBMIT響應
total_length, command_id, status = unpack('>III', resp_msg[:12])
if command_id == 0x80000004 and status == 0:
print('Submit OK')
else:
print('Submit failed')
sock.close()
3. 查詢狀態報告
下面是查詢狀態報告的示例代碼。在代碼中,需要將submit_seq_id替換成實際的提交流水號。
# 獲取消息流水號
sequence_id = random.randint(1, 65535)
# 構造CMPP_QUERY消息
query_type = 0
query_code = ''
reserve = ''
msg = struct.pack('>IIIQBB10s32s8s', 57, 0x00000006, sequence_id, submit_seq_id,
query_type, query_code.encode('gbk'), reserve.encode('gbk'), b'')
# 發送查詢消息
sock.send(msg)
resp_msg = sock.recv(1024)
# 解析CMPP_QUERY響應
total_length, command_id, status, = unpack('>III', resp_msg[:12])
msg_id, msg_status = unpack('>QH', resp_msg[12:20])
if command_id == 0x80000006 and status == 0 and msg_id > 0:
print('Message status:', msg_status)
else:
print('Query failed')
sock.close()
五、總結
CMPP2.0協議是中國移動短信網關中最為常用的一種協議,具有高效、穩定的特點。針對不同的業務需求,可以使用不同的消息類型實現短信的提交、接收、查詢等功能。本文通過分析CMPP2.0協議的結構和消息類型,並提供了相應的示例代碼,希望能夠對廣大開發者在進行短信開發時提供一些幫助。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/189970.html
微信掃一掃
支付寶掃一掃