`

浅谈CMPP3协议架构实现

阅读更多

  最近要增加短信平台对移动CMPP3协议的支持,所以就研究了下他的实现。所谓的CMPP就是中国移动通信互联网短信网关接口协议

CMPP 协议以TCP/IP 作为底层通信承载,所以开发这块需要对TCP/IP网络编程要有一定的了解。

原理:个人理解就是双方建立以什么方式来通信,就好比信是暗号写的,只有双方看的懂。

本文主要针对于长连接形式发送短信为例,而我们编写程序也只用编写在C/S架构的通讯过程中的C,然后根据服务商提供的帐号、参数经行测试。

下图是长连接的流程图。


一、实现协议步骤:

            1、建立SOKCET,启动一个线程,发送数据。

 

            2、进行链路检查,判断服务端通信是否正常等等。

            3、启动接收socket数据的线程。

二、协议代码实现:

     1、协议基本类型如下:

Unsigned Integer

无符号整数

Integer

整数,可为正整数、负整数或零

Octet String

定长字符串,位数不足时,如果左补 则补ASCII 表示的零以填充,如果右补 则补二进制的零以表示字符串的结束符

     2、消息结构:

            1)消息头(所有消息公共包头)PS:注意红色的部分是所有消息的公共头

            2)和消息体

 

三、接下来就是说说如何封装CMPP3的消息格式了,取几个谈谈就行了,原理都差不多。


 

 

 

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;

import org.apache.log4j.Logger;

//totalLength 消息总长度
//commandID命令消息类型
//sequenceID消息流水号码,顺序累加,步长为1,循环使用(一队请求和应答消息的流水号必须相同)
//Unsigned Integer 无符号整型
//Integer 整数,可为正整数、负整数、零
//Octet String 定长字符串,位数不足时,如果左补0则补ASCII表示的0以填充,如果右补0则补二进制的零表示字符串的结束符
public class MsgHead {
	private Logger logger = Logger.getLogger(MsgHead.class);
	private int totalLength; // unsigned Integer;
	private int commandID; // unsigned Integer;
	private int sequenceID; // unsigned Integer;

	public byte[] toByteArray() {
		ByteArrayOutputStream bous = new ByteArrayOutputStream();
		DataOutputStream dous = new DataOutputStream(bous);
		try {
			dous.writeInt(getTotalLength());
			dous.writeInt(this.getCommandID());
			dous.writeInt(this.getSequenceID());
			dous.close();
			return bous.toByteArray();
		} catch (Exception e) {
			if (dous != null)
				try {
					dous.close();
				} catch (Exception ee) {
				}

			logger.error("封装CMPP消息头二进制数组失败!");
			return null;
		}
	}
}

 
 

 

 代码片段:

 

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

import org.apache.log4j.Logger;

import common.msg.util.MsgUtils;

/**
 * sp请求连接到ISMG消息体定义CMPP_CONNECT操作的目的是向ISMG注册为一个合法SP身份,
 * 若注册成功后建立了应用层的连接,此后SP可以通过此ISMG接收和发送短信。 Source_Addr:Octet String
 * 源地址,此处为SP_id,即SP的企业代码 AuthenticatorSource:Octet String 用于鉴别源地址,其值通过单向MD5
 * hash计算得出,表示如下;
 * AuthenticatorSource=MD5(source_addr+9个字节的null+secret+timestamp)
 * Version:unsigned Integer 双方协商的版本号,对3.0的版本,高4BIT为3,低4位为0
 */
public class MsgConnect extends MsgHead {
	private static Logger logger = Logger.getLogger(MsgConnect.class);
	private String sourceAddr;// 源地址,此处为spID;
	private byte[] authenticatorSource;// 用于鉴别源地址
	private byte version;
	private String timeStamp;

	public byte[] toByteArray() {
		ByteArrayOutputStream bous = new ByteArrayOutputStream();
		DataOutputStream dous = new DataOutputStream(bous);
		try {
			dous.writeInt(this.getTotalLength());
			dous.writeInt(this.getCommandID());
			dous.writeInt(this.getSequenceID());
			MsgUtils.writeString(dous, this.getSourceAddr(), 6,"US-ASCII");
			dous.write(this.getAuthenticatorSource());
			dous.writeByte(this.getVersion());
			dous.writeInt(Integer.parseInt(getTimeStamp()));
			 bous.close();
			 dous.close();
			return bous.toByteArray();
		} catch (Exception e) {
			
			if (bous != null)
				try {
					bous.close();
				} catch (Exception ee) {
				}
				if (dous != null)
					try {
						dous.close();
					} catch (Exception ee) {
					}
			e.printStackTrace();
			logger.error("封装链接二进制数组失败。");
			return null;
		}

	}
}

 

 
  代码片段:

 

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

import org.apache.log4j.Logger;

import common.msg.util.MsgUtils;

public class MsgSubmit extends MsgHead {

	private static Logger logger = Logger.getLogger(MsgSubmit.class);
	private long msgId = 0;// 信息标识,8个字节的unsigned为空
	private byte pkTotal = 0x01;// 相同的msgID信息的总条数,从1开始,本业务填写1
	private byte pkNumber = 0x01;// 系统MSGID的信息序号,从1开始,本业务只填写1
	private byte registeredDelivery = 0x01; // 是否要求返回状态确认报告0不需要,1需要;
	private byte msgLevel = 0x01;
	private String serviceId = ""; // MSC4310508,业务标识是数字、字母、符号的组合

	// 计费类型0:对目的终端MSISDN计费,1对源终端MSISDN计费,2对SP计费,3表示本字段无效
	private byte feeUserType = 0x01;// 上线的确认此内容
	private String feeTerminalId = "";// 被计费的号码,当feeUserType为3时有效
	private byte feeTerminalType = 0x00;// 被计费用户的号码类型,0真实,1伪号码
	private byte tpPId = 0x00;
	private byte tpUdhi = 0x00;
	// 0ASCII码字符串,3短信写卡操作,4二进制信息,8UCS2编码,15含GB汉字
	private byte msgFmt = 0x0F;
	private String msgSrc = "";// 信息内容来源SPID;

	// 01:对“计费用户号码”免费,02:对“计费用户号码”按条计信息费
	// 03:对“被计费号码包月计费,04:对被计费号码封顶,05:对被计费号码是由SP实现;

	private String feeType = "00";// 默认按条
	private String feeCode = "000000";
	private String validTime = "";// 存或有效期限,17位长度,暂时不支持此功能
	private String atTime = "";// 定时发送时间,17位长度,暂时不支持此功能
	private String srcId = "";// 源号码,用户手机显示的号码
	private byte destUsrTl = 0x01;// 接受信息的用户数量(群发)
	private String destTerminalId = "";// 接受短信的号码
	private byte destTerminalType = 0x00;// 真实号码
	private byte msgLength;// 消息长度,小于或等于140字节
	private byte[] msgContent;// 信息内容;
	private String linkID = "";// 点播业务使用,非点播业务则不使用

	public byte[] toByteArray(String code) {
		ByteArrayOutputStream bous = new ByteArrayOutputStream();
		DataOutputStream dous = new DataOutputStream(bous);
		try {
			dous.writeInt(this.getTotalLength());
			dous.writeInt(this.getCommandID());
			dous.writeInt(this.getSequenceID());
			dous.writeLong(this.getMsgId());// Msg_Id 信息标识,由SP接入的短信网关本身产生,本处填空
			dous.writeByte(this.getPkTotal());// Pk_total 相同Msg_Id的信息总条数
			dous.writeByte(this.getPkNumber());// Pk_number 相同Msg_Id的信息序号,从1开始
			dous.writeByte(this.getRegisteredDelivery());// Registered_Delivery
															// 是否要求返回状态确认报告
			dous.writeByte(this.getMsgLevel());// Msg_level 信息级别
			MsgUtils.writeString(dous, this.getServiceId(), 10, code);// Service_Id
			// 业务标识,是数字、字母和符号的组合。
			dous.writeByte(this.getFeeUserType());// Fee_UserType 计费用户类型字段
													// 0:对目的终端MSISDN计费;1:对源终端MSISDN计费;2:对SP计费;3:表示本字段无效,对谁计费参见Fee_terminal_Id字段。
			MsgUtils.writeString(dous, this.getFeeTerminalId(), 32, code);// Fee_terminal_Id
			// 被计费用户的号码
			dous.writeByte(this.getFeeTerminalType());// Fee_terminal_type
														// 被计费用户的号码类型,0:真实号码;1:伪码
			dous.writeByte(this.getTpPId());
			dous.writeByte(this.getTpUdhi());
			dous.writeByte(this.getMsgFmt());
			MsgUtils.writeString(dous, this.getMsgSrc(), 6, code);// Msg_src
			// 信息内容来源(SP_Id)
			MsgUtils.writeString(dous, this.getFeeType(), 2, code);// FeeType
																	// 资费类别
			MsgUtils.writeString(dous, this.getFeeCode(), 6, code);
			MsgUtils.writeString(dous, this.getValidTime(), 17, code);// 存活有效期
			MsgUtils.writeString(dous, this.getAtTime(), 17, code);// 定时发送时间
			MsgUtils.writeString(dous, this.getSrcId(), 21, code);// Src_Id
																	// spCode
			dous.writeByte(this.getDestUsrTl());
			MsgUtils.writeString(dous, this.getDestTerminalId(), 32, code);
			dous.writeByte(this.getDestTerminalType());// Dest_terminal_type
														// 接收短信的用户的号码类型,0:真实号码;1:伪码

			dous.writeByte(this.getMsgLength());
			dous.write(this.getMsgContent());
			MsgUtils.writeString(dous, this.getLinkID(), 20,code);

			bous.close();
			dous.close();

			return bous.toByteArray();
		} catch (Exception e) {
			if (bous != null)
				try {
					bous.close();
				} catch (Exception ee) {
				}
			if (dous != null)
				try {
					dous.close();
				} catch (Exception ee) {
				}

			logger.error("封装短信发送二进制数组失败。");
			e.printStackTrace();

			return null;
		}
	}

 

其实这些实现挺简单的,网上也有很多类似代码,主要要明确的一点就是,客户端和服务端的通信流程和消息长度,多看协议文档。懂了原理,实现起来很简单。

最后附CMPP3协议文档。

 

 

 

 

  • 大小: 24.9 KB
  • 大小: 36.5 KB
  • 大小: 21.3 KB
  • 大小: 63.1 KB
  • 大小: 76.5 KB
分享到:
评论

相关推荐

    Java_CMPP3.0_协议实现

    Java CMPP3.0协议实现是一项针对中国移动通信网络服务提供商(SP)端网关开发的关键技术。CMPP(China Mobile Packet Protocol)是中国移动为SP提供的基于TCP/IP的数据传输协议,主要用于短信、彩信等业务的传输。CMPP...

    java实现CMPP协议

    6. **测试与调试**:在开发过程中,可以使用_cmpp3.0_文件中的样例数据进行单元测试,模拟SMSC的响应,确保协议实现的正确性。此外,日志记录也是必不可少的,它可以帮助开发者在出现问题时快速定位和解决问题。 7....

    java实现cmpp协议开发代码

    Java实现CMPP协议开发代码主要涉及的是中国移动通信的CMPP(China Mobile Packet Protocol)协议,该协议主要用于短信中心(SMSC)与短信网关(SP)之间的数据传输,包括发送短消息、接收短消息以及相关的控制功能。...

    CMPP协议的简单实现(只实现connect和submit,java实现)

    CMPP协议的简单实现(只实现connect和submit,java实现),个人闲来练手所写,在公司实际环境下测试通过,并注明详细注释,希望能对刚接触CMPP的人有所帮助,有问题可以联系qq66921494

    移动CMPP2.0和CMPP3.0协议标准

    CMPP(China Mobile Short Message Peer-to-Peer)是中国移动推出的一种用于SP(Service Provider)与移动短信...开发者在实现基于CMPP的系统时,需要理解协议细节,合理设计系统架构,以保证服务的稳定性和高效率。

    cmpp2.0 java实现

    在Java环境中实现CMPP2.0协议,可以让我们更好地理解和控制短信服务的流程。 一、CMPP2.0协议简介 CMPP2.0协议是基于TCP/IP通信协议栈的,它定义了SP和SCP之间的数据交互格式和规则。协议主要包括连接建立、消息...

    java源码实现cmpp2.0协议示例

    3. **编码与解码**:CMPP协议中的数据通常使用GBK或UTF-8编码,你需要实现编码和解码的函数,确保数据正确无误地在网络中传输。 4. **消息处理**:根据不同的命令ID,解析和处理接收到的消息,如提交短信、接收短信...

    基于中国移动cmpp3协议开发的短信网关

    在这个项目中,我们使用了C语言来实现一个基于中国移动CMPP3协议的短信网关。CMPP(China Mobile Peer to Peer)是中国移动为SP(Service Provider)提供的一个标准化接口,主要用于实现SP与移动运营商之间的数据...

    CMPP2.0协议文档

    3. **互联网短信网关(ISMG)与汇接网关(GNS)之间的接口协议**:这部分描述了ISMG与GNS之间如何建立连接、查询路由信息、更新路由配置等内容。 #### 三、缩略语及术语解释 - **ISMG (Internet Short Message ...

    CMPP2.0协议技术

    在本文中,我们将深入探讨CMPP2.0协议的核心概念、功能特性以及实现细节。 一、CMPP2.0协议概述 CMPP(China Mobile Peer to Peer)2.0协议是基于TCP/IP协议栈的,用于SP系统与移动网络之间的直接通信。它的主要...

    CMPP3.0协议源码下载

    在本资源中,包含的源码应该是实现了CMPP3.0协议的程序,能够帮助开发者快速接入中国移动的短信网关。 源码中的关键知识点主要包括以下几个方面: 1. **连接与断开**:CMPP_CONNECT和CMPP_TERMINATE是协议的基础...

    中国移动cmpp3协议ruby 源码,

    中国移动的CMPP(China Mobile Packet Protocol)协议是用于短信服务的一种通信协议,主要应用于SP(Service Provider)...通过对给定的文件进行分析和改进,可以构建一个更完善的CMPP3协议实现,满足短信服务的需求。

    基于中国移动cmpp3协议开发的短信网关源码

    【描述】"基于中国移动cmpp3协议开发的短信网关源码",意味着这个项目直接利用了CMPP3.0协议的特性,实现了短信的发送、接收和处理功能。短信网关是连接移动运营商网络和企业应用的关键组件,它允许应用程序通过标准...

    中国移动CMPP2.0协议

    3. 短信状态报告:ISMG可以通过CMPP2.0协议将短信状态报告传输到SP。 协议栈 CMPP2.0协议栈主要包括以下几层: 1. 物理层:定义了物理连接的接口和传输方式。 2. 数据链路层:定义了帧格式和错误检测机制。 3. ...

    用java实现cmpp协议

    在Java中实现CMPP协议,我们需要理解其工作原理,掌握相关的Java网络编程和数据编码知识。 1. **CMPP协议基础** CMPP协议是三层结构的协议,包括连接层、消息层和应用层。连接层负责建立、维护和断开TCP连接;消息...

    cmpp短信网关协议实现

    综上所述,"cmpp短信网关协议实现"涵盖了从理论到实践的多个方面,包括协议规范、Java实现、华为源码以及测试案例。通过深入理解和应用这些知识,开发者可以构建自己的短信服务系统,与中国移动的短信网关进行有效...

    移动运营商CMPP通讯协议文档(v2.0 、v3.0)

    3. **消息类型**:CMPP协议定义了多种消息类型,包括CMPP_SUBMIT(提交短信)、CMPP_DELIVER(接收短信)、CMPP_QUERY(查询短信状态)、CMPP_CANCEL(取消发送短信)等。每种消息类型都有特定的字段和操作流程。 4...

    中国移动CMPP3.0协议

    《中国移动CMPP3.0协议详解》 中国移动通信集团为了高效、稳定地处理大量短消息服务(SMS)和彩信服务(MMS)业务,制定了CMPP(China Mobile Packet Protocol)协议,其中CMPP3.0是其最新的版本。本文将深入探讨...

    CMPP2.0协议

    中国移动通信互联短信网关接口协议,简称CMPP2.0,是中国移动为了实现高效、稳定、安全的短信服务而制定的一种通信协议。该协议是CMPP系列协议的一个重要版本,主要针对互联网与短信网关之间的通信,为互联网应用...

    CMPP协议参考实现

    CMPP协议,全称为China Mobile Peer-to-Peer协议,是中国移动为实现SP(Service Provider)与SCP(Service Control Point)之间的高效、可靠的数据传输而制定的一套通信协议。该协议主要用于短信服务,包括发送、...

Global site tag (gtag.js) - Google Analytics