使用移动代理CMPP2.0,3.0协议实现短信发送-Java版,使用华为smproxy.jar包

本文使用的是CMPP2.0,CMPP3.0和此逻辑类似,使用的Java类不同而已

1.配置文件 cmpp.xml

 

<config>
	<!--与InfoX建立连接所需参数-->
    <ismg>
       <!-- InfoX主机地址,与移动签合同时移动所提供的地址 需修改-->
       <host>127.0.0.1</host>
       <!-- InfoX主机端口号 cmpp2.0默认为7890,cmpp3.0为7891-->
       <port>7890</port>
       <!--(登录帐号SP…ID)与移动签合同时所提供的企业代码 6位  需修改-->
       <source-addr>123456</source-addr>
       <!--登录密码 默认为空 如有需修改-->
       <shared-secret>123456</shared-secret>
       <!-- 心跳信息发送间隔时间(单位:秒) -->
       <heartbeat-interval>10</heartbeat-interval>
       <!-- 连接中断时重连间隔时间(单位:秒)-->
       <reconnect-interval>10</reconnect-interval>
       <!-- 需要重连时,连续发出心跳而没有接收到响应的个数(单位:个)-->
       <heartbeat-noresponseout>5</heartbeat-noresponseout>
       <!-- 操作超时时间(单位:秒) -->
       <transaction-timeout>10</transaction-timeout>
       <!--双方协商的版本号(大于0,小于256)-->
       <version>1</version>
       <!--是否属于调试状态,true表示属于调试状态,所有的消息被打印输出到屏幕,false表示不属于调试状态,所有的消息不被输出-->
       <debug>true</debug>
    </ismg>
</config>

2.创建SMProxy 对象,建立连接,这里最好使用单例模式创建

private static String path=Thread.currentThread().getContextClassLoader().getResource("cmpp.xml").getPath().toString();
Args args1 = new Cfg(path).getArgs("ismg");
SMProxy smProxy = new SMProxy(args1); //CMPP3.0的话就是  SMProxy30 smProxy = new SMProxy30(args1);
//path为xml文件的路径;

遇到的问题:

(1)如果报xml文件读取之类的错误,请检查XML文件的格式,查看smproxy.jar中的com/huawei/insa2/comm/cmpp/resource_zh.xml文件,修改此文件的编码格式为UTF-8(用记事本打开,另存为时选择编码);
不行的话可以用我修改过的https://download.csdn.net/download/leiliz/10878273

(2)在此之前,我们向移动对接人员提供过一个IP地址,发送短信的出口必须经过此IP地址;

3.短短信发送(短信字节(byte)少于等于140)

创建消息体:2.0举例: 

 

String[] dest_Terminal_Id = {"13200000000"};
byte[] msg_Content = "您的验证码是123456".getBytes("GB2312");
CMPPSubmitMessage submitMsg = new CMPPSubmitMessage(
	1,//@pk_Total 相同msg_Id消息总条数,短短信这里是1
	1,//@pk_Number 相同msg_Id的消息序号
	1,//@registered_Delivery 是否要求返回状态报告
	1,//@msg_Level  信息级别
	"",// @service_Id 业务类型 用户自定义 用来分类查询
	2,//@fee_UserType 0对目的终端计费;1对源终端计费;2对SP计费;
	"",//@fee_Terminal_Id 被计费用户的号码
	0,//@tp_Pid GSM协议类型 一般文本的时候设0,铃声图片设1
	0,//@tp_Udhi GSM协议类型 0不包含头部信息 1包含头部信息
	15,//@msg_Fmt 消息格式 
	"123456",//@msg_Src 消息内容来源 6位的企业代码,这里需修改
	"02",// @fee_Type 资费类别 一般为02:按条计信息费
	"0",//@fee_Code 资费代码(以分为单位)
	null,//@valid_Time 存活有效期
	null,//@at_Time 定时发送时间
	"1065760000000",//@src_Terminal_Id 移动所提供的服务代码  此处需修改
	dest_Terminal_Id,//@dest_Terminal_Id 接收业务的MSISDN号码,就是接收短信的手机号,String数组
	msg_Content,//@msg_Content 消息内容 byte[],发送的消息内容,需要转化为byte[]
	"" //预留
);
CMPPSubmitRepMessage sub = (CMPPSubmitRepMessage)smProxy.send(submitMsg);//这里的smProxy就是第2点中用单例创建的smProxy对象
if(sub.getResult() == 0){
	//发送成功
}

 

4.长短信发送(内容大于140字节)

首先要将内容按140长度分割,得到一个数组或List,也是byte[],例如List<byte[]>

附上分割短信的全部代码,一个类:

public class LongMessageByte {
	public static List<byte[]> getLongByte(String message){
		List<byte[]> list = new ArrayList<byte[]>();
		try {
			byte[] messageUCS2 = message.getBytes("UnicodeBigUnmarked");//转换为byte[]
			int messageUCS2Len = messageUCS2.length;// 长短信长度
			int maxMessageLen = 140;
			if (messageUCS2Len > maxMessageLen) {// 长短信发送
				//int tpUdhi = 1; 
				//长消息是1.短消息是0
				//int msgFmt = 0x08;//长消息不能用GBK
				int messageUCS2Count = messageUCS2Len / (maxMessageLen - 6) + 1;// 长短信分为多少条发送
				byte[] tp_udhiHead = new byte[6];
				Random random = new Random();
				random.nextBytes(tp_udhiHead);//随机填充tp_udhiHead[3] 标识这批短信
				tp_udhiHead[0] = 0x05;
				tp_udhiHead[1] = 0x00;
				tp_udhiHead[2] = 0x03;
//				tp_udhiHead[3] = 0x0A;
				tp_udhiHead[4] = (byte) messageUCS2Count;
				tp_udhiHead[5] = 0x01;// 默认为第一条
				for (int i = 0; i < messageUCS2Count; i++) {
					tp_udhiHead[5] = (byte) (i + 1);
					byte[] msgContent;
					if (i != messageUCS2Count - 1) {// 不为最后一条
						msgContent=byteAdd(tp_udhiHead,messageUCS2, i*(maxMessageLen-6),(i+1)*(maxMessageLen-6));
						list.add(msgContent);
					} else {
						msgContent=byteAdd(tp_udhiHead,messageUCS2, i*(maxMessageLen-6), messageUCS2Len);
						list.add(msgContent);
					}
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	private static byte[] byteAdd(byte[] tpUdhiHead, byte[] messageUCS2, int i,int j) {
		byte[] msgb = new byte[j-i+6];
		System.arraycopy(tpUdhiHead,0,msgb,0,6);
		System.arraycopy(messageUCS2,i,msgb,6,j-i);
		return msgb;
	}
}

 

举例:

 

String[] dest_Terminal_Id={"13200000000"};
List<byte[]> list = LongMessageByte.getLongByte("您好!哈哈哈哈哈哈哈哈哈哈哈哈......");//截取短信内容并配置参数,这个内容要大于70汉字
for (int i = 0; i < list.size(); i++) {
	CMPPSubmitMessage submitMsg = new CMPPSubmitMessage(
		list.size(),//@pk_Total 相同msg_Id消息总条数 
		i+1,//@pk_Number 相同msg_Id的消息序号
		1,//@registered_Delivery 是否要求返回状态报告
		1,//@msg_Level  信息级别
		"",// @service_Id 业务类型 用户自定义 用来分类查询
		2,//@fee_UserType 0对目的终端计费;1对源终端计费;2对SP计费;
		"",//@fee_Terminal_Id 被计费用户的号码
		0,//@tp_Pid GSM协议类型 一般文本的时候设0,铃声图片设1
		1,//@tp_Udhi  0不包含头部信息 1包含头部信息 必须为1
		8,//@msg_Fmt 消息格式 设为UCS2编码
		"123456",//@msg_Src 消息内容来源 6位的企业代码
		"02",// @fee_Type 资费类别 一般为02:按条计信息费
		"0",//@fee_Code 资费代码(以分为单位)
		null,//@valid_Time 存活有效期
		null,//@at_Time 定时发送时间
		"106576000000",//@src_Terminal_Id 移动所提供的服务代码 此处需修改
		dest_Terminal_Id,//@dest_Terminal_Id 接收业务的MSISDN号码
		list.get(i),//@msg_Content 消息内容 byte[]
		"" //预留   3.0这里是String LinkID,点播业务使用的LinkID,非点播类业务的MT流程不使用该字段。
	);
	CMPPSubmitRepMessage sub = (CMPPSubmitRepMessage)smProxy.send(submitMsg);//这里的smProxy就是第2点中用单例创建的smProxy对象
	if(sub.getResult() == 0){
		//本条发送成功
	}
}

移动会把多条短信(长短信分割)合成一条发送到手机

如果要使用3.0 更换以下类

SMProxy -->SMProxy30

CMPPSubmitMessage -->CMPP30SubmitMessage

CMPPSubmitRepMessage -->CMPP30SubmitRepMessage

如有问题请联系

  • 11
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 49
    评论
功能特点: 1.遵照CMPP2.0协议实现,模拟了短信网关,支持CONNECT,SUBMIT,DELIVER,QUERY,CANCEL,TERMINATE消息。 2.支持多个客户端登录,支持单连接和双连接类型,支持标准CMPP和亚信API. 3.服务端自动生成Msgid,支持状态报告. 4.支持对客户端进行鉴权,用户可以自行配置有效的客户端ICPID,SPID,PWD,和有效的IP地址。 5.以二进制形式显示消息流内容,并且能够把消息包的每个字段都打印出来,当然这会影响一些效率。 6.模拟网关不对submit各字段的合法性进行判断(如msgsrc必须是企业代码icpid,srcid必须是接入号 发送错误代码介绍:0 = TRS_SUCCESS : 正确 1 = TRS_PACKET_ERR : 消息结构错 2 = TRS_CMD_ERR : 命令字错 3 = TRS_SEQ_DUPLICATE : 消息序号重复 4 = TRS_PACKET_LEN_ERR : 消息长度错 5 = TRS_FEE_ERR : 资费错 6 = TRS_MSG_LEN_ERR : 超过最大信息长 7 = TRS_SRV_CODE_ERR : 业务代码错 8 = TRS_FLUX_ERR : 流量控制错 9 = TRS_NOT_SRV_USER : 本网关不负责服务此计费号码,前转判断错(此SP不应发往本ISMG) 10 = TRS_SRC_ID_ERR : Src_Id错误 11 = TRS_MSG_SRC_ERR : Msg_src错误 12 = TRS_FEE_TERMINAL_ERR : Fee_terminal_Id错误 13 = TRS_DEST_TERMINAL_ERR : Dest_terminal_Id错误 160 = IP_ADDRESS_ERR : ZTE_EXTENED 帐号源IP地址错误 161 = LINK_FULL : ZTE_EXTENED 帐号已经建立了15条链路 162 = LOCK_MUTEX_ERR : ZTE_EXTENED 建链时锁错误 163 = RGSTRDDLVRY_ERR : ZTE_EXTENED Registered_Delivery取值错误 164 = FEEUSERTYPE_ERR : ZTE_EXTENED FeeUserType取值错误 165 = TERMINALTYPE_ERR : ZTE_EXTENED TerminalType取值错误 166 = MSGFMT_ERR : ZTE_EXTENED MsgFmt取值错误 167 = MSGFWDTYPE_ERR : ZTE_EXTENED msgFwdType取值错误 168 = USERTYPE_ERR : ZTE_EXTENED UserType取值错误 169 = ROUTE_ERR : ZTE_EXTENED 路由失败 170 = SMMC_ERR : ZTE_EXTENED 信息过滤失败 171 = IAGWM_LINK_DOWN : ZTE_EXTENED 与IAGW M模块断链 172 = SEND_AUTH_ERR : ZTE_EXTENED 给IAGW M模块发消息失败,非断链 173 = AUTH_ERR : ZTE_EXTENED IAGW M认证失败 174 = LICENSE_FAILED : ZTE_EXTENED 超过系统license限制 175 = TRANS_ERR : ZTE_EXTENED 消息转发错误 176 = RESP_TIME_OUT : ZTE_EXTENED 等resp超时 177 = FATAL_ERR : ZTE_EXTENED 当错误码为-1时转换为此值

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 49
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值