一、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