王朝网络
分享
 
 
 

在CMPP2.0 协议SP端的.NET开发

王朝c#·作者佚名  2008-05-31
宽屏版  字体: |||超大  

一、CMPP协议简介

中国移动通信互联网短信网关接口协议(China Mobile Peer to Peer CMPP),是中国移动梦网内部各SMS参与节点相互交换SMS的官方协议。作为梦网的参与方,移动梦网的增值服务商(Service PRovider SP )要按照此协议规范实现SP的部分,才可以将自己的短信通过移动的GSM网络的数据通道传输到最终手机用户上。

实际上,协议规范了3个方面的内容:

SP与移动的互联网短信网关(Internet Short Message Gateway,ISMG)之间的接口协议

ISMG之间的接口协议(譬如移动各省、市之间的短信息交换通过ISMG之间进行)

ISMG与汇接网关(Gateway Name Server GNS,类似互联网上的DNS服务器)之间的接口协议,譬如跨省之类的短信需要GNS的帮助指出当前ISMG该如何传递短信。

其中,后二方面属于移动短信息系统内部实现,对于SP来讲大概可以“透明”来看待,只要实现了SP同ISMG的正确交互,就可以实现接入移动梦网短信系统。我们关心的只是SP端的开发细节。

二、CMPP交互模式

从手机用户角度讲,按短信的发起/接收路径来讲,有两个叫法:

MT(Short Message Mobile Terminated, SMMT),短信接收,短信从SP发送到手机用户。

MO (Short Message Mobile Originate,SMMO),短信发送,短信从手机用户端发送到目标SP。

这两类短信交互,从SP端来看,都是属于Socket传输应用,CMPP的协议是以TCP/ip协议作为底层承载协议的,属于TCP/IP协议栈之上的应用。

SP同ISMG的交互连接分长连接和短连接。

所谓短连接,就是一次连接,传输一个消息,然后等待回复后拆除连接,显然,效率很低,所以,基本上不被考虑(实际应用移动也不答应SP采用短连接,只是不明白移动为什么还要写入文档? ISMG间会需要?)

所谓长连接,就是SP建立同ISMG连接,然后不断将数据包(一个个CMPP消息)发送到ISMG,此处发送不必等待某条消息的ISMG回应消息返回,就接着发送下一个消息。同时,等待ISMG返回信息或者等待ISMG发送给SP的消息。发送同接收消息不是一定要同步的,实际采用异步(同时也时双工)模式。从效率上,显然,必须全双工的异步模式才能够满足实际应用需求。

三、SP端开发

1.消息分类

首先,图中的CMPP消息有很多种,SP同ISMG之间交流这些消息。大体上这些消息发出后,对方往往需要回复一个应答(RESP)类消息。注重,这些消息大多具有方向性,也就是说只能够从一端到另一端,而不可反方向进行,有些(少数)则可两端都能够发出。以下信息主要来源于移动的文档,但针对大家易混淆或源文档解释不够具体做了明确和补充。具体见下表:

2.交互阶段

整个CMPP协议交互分为验证、事务两个阶段。验证阶段,发送CMPP_CONNECTION消息进行验证,通过验证后(必须要通过才)进入CMPP事务阶段,可以发送短信数据了。上表中的CMPP_CONNECTION以下的消息都属于事务阶段的消息。

3.消息数据结构

每一个消息包含 消息头 和 消息体两个部分,头固定长度为12字节,其他消息长度各异,但是同一类型消息的长度是固定的。所有消息的各个字段基本上仅有3种类型:Unsigned Integer (无符号整型)、Integer(整型)、Octet String(字符串),每种类型具体长度不定,网络字节顺序。

1、消息头(3个Unsigned Integer字段组成):

4字节的Total_Length (Unsigned Integer),包含了此消息的总计(包括了头部分)长度。

4字节的Command_Id(Unsigned Integer),指明了此消息到底是什么消息,就是上表中消息的枚举值。应用程序根据此值确定本数据包到底是什么消息,从而可以按照确定的消息类型,解析余下的消息体。

4字节的Sequence_Id(Unsigned Integer),指明了此数据包在发送此消息端的唯一编号。这个唯一编号,实际上可以看作流水操作编号。因为分析到交互模式我们看到,SP发送数据到ISMG,不是每发送一个就停下来等待ISMG的回复,而是“一下子”发送多个数据包过去,然后等待ISMG的回应。然而,怎么知道回应的消息是到底对应之前发送过去的消息中的那一条呢?本字段就是解决此难题。SP按照编号发送消息过去,等待ISMG的回应—一般情形下回应消息数据结构都有表明本消息回应的是SP发出的哪一条消息,这个对应就是依靠Sequence_Id。它并不要求一定要严格唯一,但是在给定的一段时间内,必须唯一(基本上只要SP发送过去的消息中没有重复就行了)。假如是需要SP回答的消息,SP也必须将ISMG发送过来的消息的Sequence_Id填入相应字段,表明这是某个消息的回应。SP端和ISMG端Sequence_ID都没有确定具体的算法。SP可以(但不推荐)采用数据库的唯一Id作为此值。

2、消息体。消息体长度根据消息不同,长度不一。其他的参考移动的文档《中国移动通信互联网短信网关接口协议(China Mobile Peer to Peer, CMPP)(V2.0)》,这里着重讲讲2个重要消息的消息体数据结构:

CMPP-_SUBMIT的消息体:

CMPP_SUBMIT消息长度是可变的,将SP端的消息发送给ISMG,ISMG将返回一个MSGID给SP标示此消息,之后(48小时以内,但一般最多几分钟内就可),ISMG返回关于此消息的递送报告。递送报告同MO短消息是通过另外一个重要消息CMPP-_DELIVER来提交给SP的:

CMPP-_DELIVER的各个字段:

假如是报告,那么Msg_Content将按照状态报告结构来解释:

关于State字段,如下解释:

4.安全验证

CMPP协议在CMPP_CONNECT中传递验证消息。验证消息为9字节的0+移动给出的密码+当前时间戳字节数组的md5算法后的字节。时间戳为 月日时分秒,10位。代码算法如下:

private byte[] getMd5Code()

{

byte[] buf=new byte[6+9+_PassWord.Length+10] ;

byte[] s_a=Encoding.ASCII.GetBytes(_SystemID); //就是企业代码

byte[] s_0={0,0,0,0,0,0,0,0,0}; //9字节的0,此处当作右补0

byte[] s_p=Encoding.ASCII.GetBytes(_Password); //密码

this._timestamp =getTimestamp();//取得认证码时赋值字符串

byte[] s_t=Encoding.ASCII.GetBytes(_timestamp); //10位字符串字节数组

s_a.CopyTo(buf,0);

s_0.CopyTo(buf,6);

s_p.CopyTo(buf,6+9);

s_t.CopyTo(buf,6+9+_Password.Length);

MD5 md5= new MD5CryptoServiceProvider(); //创建MD5类别

return(md5.ComputeHash(buf,0,buf.Length));

}

其中getTimestamp函数为返回例如“0710125959”(7月10号12点59分59秒)这样的字符串,具体代码略过,有爱好请查看本文的附件代码。

5.厂商API问题

笔者公司所处广东,广东移动提供了华为的以C 形式的API(SMEIDLL.dll),来帮助大家初期熟悉CMPP协议。但是,经过开发测试,发现华为的API至少存在几个问题:

1、封装成几个API函数,但是由于CMPP自身的复杂性,导致这些函数丑陋无比,参数多,而且难以明晰含义。华为的API,内部将CMPP的验证、事务阶段分成几个函数实现,其中将发送SMS到ISMG功能以函数提供,竟然出现SubmitAExExEx之类的函数说明。

2、CMPP的交互是异步的,需要多线程实现一边发送,一边接收反馈信息。此API应当是内部维护一个线程进行CMPP_SUBMIT消息发送,但是华为API却通过空循环之类的操作等待ISMG返回CMPP_SUBMIT_RESP得到相应的MSGID再返回(从而实现消息同步返回)。经过测试,大约需要200毫秒,这个在实际SP的高性能需求场合根本无法满足系统要求。

3、接收短信必须依靠程序主动先发出函数HasDeliverMessage调用 ,得到有消息才可通过GetDeliverSMEx函数获取消息,显然,这种方式是低效率的,而且轻易产生消息数据包丢失,表现为有些MO消息,SP接收不到。而且,令人迷惑的是,你还不能够新开一个线程专门来做判定并接收MO的动作,实际开发中一旦采用线程来做就回发生内存保护错误(大概属于同API自身的线程有冲突)。

4、返回错误码,往往又是华为自己定的一套错误码(大概华为设计此API为了适应SMGP CMPP等多个协议),而且经常变动,很是伤脑筋。

基于以上理由,我认为自己按照CMPP协议开发一个SP端程序,比较能够满足一般SP的需求。

四、C#实现

1、CMPP协议实现类CMPPClient

通过研究,笔者用C#写了一组类实现自己的CMPP SP端程序(CMPPClient)。为了实现相关类,还需要编写一些辅助类,并且首先要解决CMPP协议的数据结构同C#的数据之间的转换问题。

CMPP的Octet String 实际上相当于C#中的byte[],所有CMPP消息的Octet String字段出了CMPP_SUBMIT和CMPP_DELIVER的msg_content字段外,其他的都可以认为是ASCII编码,所以全部可以采用System.Text.Encoding.ASCII进行编码和解码;对于Msg_Content字段,由于一般情况下存在汉字信息传输.,所以默认的编/解码应该为Encoding.Default,实际是什么编码还要考察MSG_Fmt字

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有