前段时间,一直忙于公司的短信接口的研发;虽然总是忙,但还是非常有收获的。从短信开接口的研发中也碰到不少问题,相信和我相同,大家在研发网关接口时也会有不少问题会碰到的:比如,采用移动提供的API出错,不同的编码,计费拔测,接收问题等。其实对于自己的上层领导来说,他所要的是结果,致于研发过程中你所遇见的各种问题都是自己去解决的,不懂就上网找,或说问一下有这方面研发经验的朋友或同学。正是由于不同的研发人员在做CMPP(移动)协议或是SGIP(联通)、SMGP(小灵通)协议时所碰到的问题相信有非常大一部分是相同的,在这里我就把我研发过程中的一些碰到的问题和经验写出来,希望对准备研发短信网关协议的研发人员有一定的帮助,同时也希望大家如果有更好的经验也能贴出来,这样能使大家在研发上都会轻松一些。不过大家也能到这个网站
http://skybird.9s9s.com/bbs/index.asp
。能说我也是从上面学到不少东西,在这先感谢各位贴出自己经验的朋友。
说了这么多费话,下面还是转入正题了。下面说主要以中移动的CMPP2.0协议来说明,还会说到API的研发的问题,希望对于想自己研发API的朋友也有一定帮助。
对开手上还没有CMPP协议的朋友,能到上面说的那个网站去下载,能以直接到
http://www.gd.chinamobile.com/
(广州移动)上面下载。对于广州移动所用的是华为的短信网关,在接入是移动方面提供了网关二次研发的API,不过相信用过华为提供的API的人总会是有苦说不出,在这里我也不再多用评论,因为最初时间比较紧迫,所以也用过这个API的,但最终还是自已去研发了。
移动梦网和联通在信都是构建在有中国特色的短信网关部件基础上的,亚信为中国移动设计的CMPP协议规范,中国联通的SGIP规范都是为这个短信网关提供的互连网接口标准,能看出二者都是借鉴GSM SMPP协议的两种简化版。
CMPP提供了基于TCP的长连接接口和短连接接口标准,SGIP提供了基于TCP和HTTP/TCP的短连接接口标准。CMPP中的短信网关为TCP服务器,通过接收SP发起的TCP连接来发送MT/MO/Report/Resp等消息。SGIP中发送MT/MTResp时是短信网关为TCP服务器,发送MO/MOResp/Report/ReportResp时短信网关作为TCP客户端。
长连接接口
通信双方以客户-服务器方式建立TCP连接,用于双方信息的相互提交。当信道上没有数据传输时,通信双方应每隔时间C发送链路检测包以维持此连接,当链路检测包发出超过时间T后未收到响应,应即时再发送链路检测包,再连续发送N-1次后仍未得到响应则断开此连接。
短连接接口
通信双方以客户-服务器方式建立TCP连接,应答和请求在同一个连接中完成。系统采用客户/服务器模式,操作以客户端驱动方式发起连接请求,完成一次操作后关闭此连接。
设计CMPP 协议API模块,要考虑以下几个问题:
1、 链路检测。类似链路检测的长连接维持机制,为每个连接,在最后一个消息的处理结束前,重新启动一个60秒(能自定义时间长短)的定时器。如果期间有消息来往,停止定时器,处理完消息后,继续启动定时器。如果60秒超时,重新启动定时器,连续三次超时,关闭这个链接,重新启动建立过程
2、 超时重发和差错重发。超时重发的原理是发送每个MT消息后,启动一个60秒的定时器,等待网关返回应答。如果超时,继续发送,连续3次都超时都没有应答,关闭连接,启动链路恢复过程。并返回一个发送超时的信息给调用这个API的用户接口。差错重发是接受到错误的应答,并且这个错误是由对等通信双方的协议层产生的,那么重新发送这条消息。
3、 滑动窗口控制流量。能实现流量控制和有效的负载均衡。滑动窗口大小为16条消息。采用异步方式,一次发送16(称动建议值)条消息,并等待应答,每成功一个应答,窗口缩小,然后再从缓存取一个发送,填满窗口。但为了确保每一个发送的直接回应,能只设置滑动窗口大小为1条消息,这样调用API的客户端程式能直接得到发送的回应结果。方便客户端程式的自由的自动重发机制。
4、 消息重复处理。缓存当前所接收到的消息编号,确保所收到的消不能是回转重复。这个编号要靠短信网关来控制唯一性。当然,自已发送的数据包也要确保在一个链接段内时唯一的,这样才能确保数据的正确性。
5、 短信网关消息接收缓存。如要采用回调函数的方法传送接收信息给调用API的客户端程式,能不考虑接收缓存,而采用API缓存方式接收时,要注意控制接收的量,以确保信息处理的及时性。
6、 有序控制。是保障先来的消息,先发送出去,后来的后发,严格地保障先后顺序。是通过序列号和滑动窗口来保障的。实际应用中,倒是不那么严格地关注顺序发送问题。
上面说了这么多都是一些技术结构上的问题,并没有实际到研发中的问题。其实做为一个研发人员,首先要做好的就是整个架构搭建的问题,代码实现是其次。因为有了好的架构,实现起来并不是非常难(对于经常研发项目的研发人员来说),能说是磨刀不误砍柴功。下面结给API的研发来说一下CMPP协议的研发。
其实说到API的开发,也只是包装了一个通讯协议。让上层用户可以不用去知道详细的协议解释,而专注于自己的业务模块。
对于CMPP2.0协议,要用的指令也就8个,相对来说并不是很复杂
CMPP_CONNECT =0x00000001; // 请求连接
CMPP_CONNECT_RESP =0x80000001; // 请求连接应答
CMPP_TERMINATE =0x00000002; // 终止连接
CMPP_TERMINATE_RESP =0x80000002; // 终止连接应答
CMPP_SUBMIT =0x00000004; // 提交短信
CMPP_SUBMIT_RESP =0x80000004; // 提交短信应答
CMPP_DELIVER =0x00000005; // 短信下发
CMPP_DELIVER_RESP =0x80000005; // 下发短信应答
CMPP_QUERY =0x00000006; // 短信状态查询
CMPP_QUERY_RESP =0x80000006; // 短信状态查询应答
CMPP_CANCEL =0x00000007; // 删除短信
CMPP_CANCEL_RESP =0x80000007; // 删除短信应答
CMPP_ACTIVE_TEST =0x00000008; // 激活测试
CMPP_ACTIVE_TEST_RESP =0x80000008; // 激活测试应答
实现CMPP协议模块也就是实现上面的8个指令就可以了。按照上面说的设计模式,同进结合API开发来说一下协议的实现。
对于API对外的接口,一般的定义格式如下:
extern "C" __declspec( dllexport ) int WINAPI ActiveTest()
接下来就是实现接口的功能:
一、建立SOCKET连接
struct sockaddr_in _socaddr ;
_socaddr.sin_family = AF_INET;
_socaddr.sin_port = htons( _port );
_socaddr.sin_addr.s_addr = inet_addr( _ismg );
return connect( _soc, (struct sockaddr *)&_socaddr, sizeof( _socaddr ));
致于设置发送超时,接收超时还有阻塞或非阻塞的接收模式,可以自己根据需要去设置不同的目标值。
二、登录短信网关服务器
-
按CMPP协议,主要的部分是就是AuthenticatorSource = MD5(Source_Addr+9 字节的0 +shared secret+timestamp),MD5算法在网上可以直接找到源程序,不必要自己重新去写这个内容。这部分内容相对比较简单就不在这里再写出来了。
//计算单向HASH函数的值
strcpy( authsrc, _spid ) ;
char * pos = authsrc + strlen( _spid ) + 9 ; //9 字节的0
strcpy( pos, _passwd ) ;
pos += strlen( _passwd );
strcpy( pos, _timestamp( timestr )); //时间戳
pos += strlen( timestr );
ctx.update(( unsigned char * )authsrc, (int)( pos - authsrc ));
ctx.finalize();
ctx.raw_digest( msg->digest ); //复制转换成MD5的字符串到发送数据中
三、提交短信息
相对于登录来说,提交短信也不会很复杂。只是简单的把客户端程序提交过来的数据复制到发送窗口,发送并等待网关回应的状态就可以了,当然也可以在接收到用户的数据前作一些适当的如:手机号码是否全数字,定时发送或存活时间是否正确等的判断。
//要注意的就是可变的用户数据与保留字段的内容:
memcpy( _pkg->data, &msg, sizeof( CMPP_SUBMIT ));
//将最后8个字节的保留数据拷贝到适当的位置
memcpy(
( _pkg->data + nsize - sizeof( msg.reserve ) - sizeof( CMPP_HEAD )),
msg.reserve,
sizeof( msg.reserve ));
四、接收短信息和状态
接收短信后有两种处理方式,
1、 采用回调函数的方式:
这种方式相对于API来说比较简单,只要定义一下接口函数就可以了,客户端程序在初始化时,传入回调函数的函数指针,当API接收到短信网关下发(DELIVER)的短信时,调用函数指针把相关参数据传递给客户端。不必要考虑队列或其它细节的问题。
如下我在API中定义的回调函数:
typedef int ( WINAPI * TProcGetDeliver )(
char * msgid,
unsigned char * destnumber,
unsigned char * serviceid,
unsigned char tppid,
unsigned char tpudhi,
unsigned char msgfmt,
unsigned char * srcnumber,
unsigned char delivery,
unsigned char msglen,
unsigned char * msgcontent,
unsigned char * reserve,
unsigned char * stat,
unsigned char * submittime,
unsigned char * donetime ) ;
而在API对外接口中只要定义一个参数作为传送函数指针就可以了:如下:
extern "C" __declspec( dllexport ) int WINAPI IFInitInterface( char *ismg, unsigned short port, TProcGetDeliver fCltGetDeliver );
fCltGetDeliver 就是用户传递过来的回调函数指针,在调用时,直接采用参数开式用调用就可以了。如下所示:
err = _fCltGetDeliver ( (char * )&_msgid,
_msg->destnumber,
_msg->serviceid,
_msg->tppid,
_msg->tpudhi,
_msg->msgfmt,
_msg->srcnumber,
_msg->delivery,
_msg->msglen,
_msg->msgcontent,
_msg->reserve,
_stat,
_submittime,
_donetime
) ;
这样所接收到的所有参数就顺利传递到客户端了。
2、 调用API的客户端程序定时检测并从缓冲队列中拾取方式:
对于队列的方式,API内部必需自己建立一个缓冲队列。这个队列对于安全来说,必须是线程安全的(可以用临界区来保护),接收到一个下发信息时,数据暂时保存入队列中:
int nl = sizeof( CMPP_HEAD ) + sizeof( CMPP_DELIVER ) ;
_pushrecqueue( _recpkg, nl ) ;
下面是_pushrecqueue函数;
void WINAPI _pushrecqueue( void * inval, int nl )
{
char * _queval = new char[ nl + 1 ] ;
memset( _queval, 0, sizeof( nl + 1 )) ;
memcpy( _queval, inval, nl ) ;
_queue._push( _queval ) ;
}
为了保证数据最大安全性,不要接收到过多的数据进入队列。放入队列的数据就等待用户用API接口过来取走就可以了,其相关接口与回调函的参数相差不多,在这里就不多作说明,只要说明一下可以提供一个接口,可以让客户端可以检测队列中是否有可以接收的数据:
extern "C" __declspec( dllexport ) int WINAPI HasDeliver() ;
这检是否取数据就由客户端去作判断了。
五、发送接口
对于API来说,最重要的一部分就是去做发送数据了。通过SOCKET套接字与网关相连接后,将自己的数据发送出去。
在发送数据前,组装好要发送的数据包,将数据COPY一份到发送窗口,对于不要回应的数据包,只要发送成功,就可以退出发送进程。对于要等待回应的包,启动一个时钟来作为检测是否收到了回应,并返回结果给发送窗口。设置发送的次数标志,如果发送第一次超时,按设定的发送次数,再发送。如果出现一次发送不成功,可以设置一个标志位,去发送一次链路检测标志,如果链路检测失败,应该重新连接或者是在用户发送时直接返回链路断开的结果。
CMPP_PACKAGE * _pkg = ( CMPP_PACKAGE * )buf ;
int err = API_E_UNKNOW_ERR ;
if( _soc == INVALID_SOCKET ) return API_E_INVALT_SOC ;
while( _pkg->n > 0 )
{
_pkg->n = _pkg->n - 1 ; //发送次数
_lastacttime = time( NULL ) ;
EnterCriticalSection( &_csec_soc ) ;
try
{
err = send( _soc, buf, len, 0 ) ;
}
catch( ... )
{
}
LeaveCriticalSection( &_csec_soc ) ;
if( err < len ) //发送不成功
{
err = API_E_SO_SENDERR ;
continue ;
}
//不要回应结果的直接跳出
if( _pkg->resp == false )
{
err = 0 ;
break ;
}
//等待回应事件
…………
}
//如果发送超时,设置发送链路检测标志开
if( err == API_E_SO_OVETIME )
{
_needacttest = _needacttest + 1 ;
}
return err;
六、接收接口
对于数据的接收,因为发送短信的接口的数据量并不是很大,所以可以采用接收到
一部分,解释一部分的功能,这样的就可以减少设计上的难度,当然也可以一次接收缓冲中的数据,再一段段去分析,也不是很难。
对于接收,启用一个新的线程,这样也可以保证接收的及时性与可调度性。先接收包头信息确定整个数据包的长度,直到接收到一个完整的包的内容才进行下一个包的接收,有些包也可能是没有包体结构的,所以也可以在收到正确的包头后就进行分析结构如下:
//先接收包头部分,以确定包的大小、类型
err = _pscoket->_recv( _pscoket->_rec_window, sizeof( CMPP_HEAD )) ;
if( err == SOCKET_ERROR || err == API_E_INVALT_SOC ) continue ;
CMPP_PACKAGE * _recpkg = ( CMPP_PACKAGE * )_pscoket->_rec_window ;
if( ntohl( _recpkg->head.size ) > 0 )
{
//接收包体
_reclen = 0 ; //已接收长度
_recdatalen = ntohl( _recpkg->head.size ) - sizeof( _recpkg->head ) ;
do
{
Sleep( 1 ) ;
_recdatalen = _recdatalen - _reclen ;
err = _pscoket->_recv( _recpkg->data + _reclen, _recdatalen );
if( err == SOCKET_ERROR || err == API_E_INVALT_SOC ) continue ;
_reclen = err ;
} while( _recdatalen - _reclen > 0 ) ;
if( _recdatalen > _reclen ) continue ;
}
try
{
_pscoket->_analysisrecpack( _recpkg ) ; //分析包的内容
}
catch( ... )
{
}
七、分析协议包
接收到CMPP的一个完整的协议包后,根据命令字去作分析,相对来说并不是一个很难的事情,不过要注意是就是要把网络数据流转化为主机数据流这个问题。
unsigned char _result = 0 ;
CMPP_DELIVER * _msg = ( CMPP_DELIVER * )_recpkg->data ;
DELIVER_CONTENT * _pcont = ( DELIVER_CONTENT *)_msg->msgcontent ;
八、链路检测
根据CMPP协议当链路检测包发出超过时间T后未收到响应,应立即再发送链路检测包,再连续发送N-1次后仍未得到响应则断开此连接,并根据需要重新建立链接(T=60秒,N=3)。但也能够加快链路检测的速度;这个并不影响API的正常运行:
在线程中添加一个检测的事件,当检测到要发送链路检测时,触发链路检测线程:
//要链路检测测试( 链路是每30秒发送一次数据 )
if( _pscoket->_needacttest > 0 || _pscoket->_lastacttime
{
_pscoket->_lastacttime = time( NULL ) + 1 ;
SetEvent( _pscoket->_hevnt_acti ) ;
}
//链路检测线程部分代码:
if( WaitForSingleObject( _pscoket->_hevnt_acti, _pscoket->_dwmsec ) == WAIT_OBJECT_0 )
{
try
{
err = _pscoket->_ActiveTest() ;
}
catch( ... )
{
}
//根据发送链路检测结果来作进一步动作
if( err != 0 )
{
//重发可断开链接,重新初始SOCKET接口等
………….
}
致此,我基本上已把整个CMPP协议的研发过程写完,中间还附带了部分代码,希望对大家有所帮助,假如有什么不明的也能够直接写邮件到我的邮箱
jimzj@21cn.com
,我将为您解答一些CMPP研发中的问题或是计费拔测碰到的字段配置的问题(能够是移动梦网,联通在线或电信巨龙)。
九、短信二次研发
另外对于没有申请到移动或联通短信接口的用户,能够通过提供的一套
API接口,能够快速的通过此API接口发送短信息:研发包包括以下内容:
5.0、文档说明
目录名
子目录名
文档名
功能说明
BGAPI
Exam_BC
BCB例程
Exam_VC
VC例程
FuncDef.cpp
动态库调用cpp文档
FuncDef.h
动态库调用h文档
BGAPI.Dll
动态库
短信API客户端研发使用说明.doc
说明文档
大家假如要下载这个研发包,能够到
www.ebase168.com
上的短信快车主页面中的二次研发就能够下载,测试。所附带的两个例程中已有登录用户的企业名称和密码,通过这个API,用户还能够自已做一个企业服务器,再下带10万个客户端,这样去研发自己的客户群。
研发所要的几个接口的定义:
5.1初始化API函数函数名:_IFInitInterface()
功能:完成初始化的工作;
1)、系统资源的初始化:系统资源的创建和配置;定时资源的配置;通信消息机制的配置;内存管理的初始化配置;
2)、通信参数初始化:包括服务器端IP地址;客户端器端IP地址;通信端口号;
3)、尝试连接;
返回: 0 成功
1 参数 fCltDeliver 不能为空
2 参数 fCltSmsStatus 不能为空
3 初始化异常
99 系统错误
说明:
参数中的所要的回调函数用于在接收到中央服务器下发的短信或短信状态是调用,用户应在接收到后,把信息保存后尽快返回一个0表示成功接收到短信或状态,不要在回调函数中直接处理信息或状态,以免影响接收的速度;回调函数的定义请参见FuncDef.h中的定义;
5.2登录注册函数函数名:_Login()
功能:完成向中央服务器注册的工作;
1)、检测用户参数是否正确;
2)、向中央服务器发出一个注册指令;
返回: 0 登录已提交
1 未初始化
2 企业代码
3 用户名称
5.3短信提交函数名:_Submit()
功能:向中央服务器提交一条短信息;
1)、检测用户提交的参数是否正确;
2)、向中央服务器发出短信提交指令;
说明:
返回: 0 提交成功
1 未初始化
2 未注册
3 注册接收地址有误
4 原始编码
5 源地址含有非法字符(只能空或数字)
6 源地址长度 > 5
7 目标地址含有非法字符(只能数字)
8 目标地址
9 编码
10 数据长度
11 中文 > 65个字符 或 英文 > 130个字符
12 流量限制 条/秒
13发送失败
5.7接收短信息回调函数函数名:TProcGetDeliver()
功能:用来接收中央服务器下发的短信;
1)、接收短信息;
返回: 0 客户端成功接收
说明:
回调函数用于在接收到中央服务器下发的短信,用户应在接收到后,把信息保存后尽快返回一个0表示成功接收到短信,不要在回调函数中直接处理信息,以免影响接收的速度;回调函数的定义请参见FuncDef.h中的定义;
5.8接收短信状态回调函数函数名:TProcGetSmsStatus()
功能:用来接收中央服务器下发的状态;
1)、接收注册回应;
2)、接收通讯测试状态
3)、接收提交短信返回状态
4)、接收短信回应状态
返回: 0 客户端成功接收
说明:
回调函数用于在接收到中央服务器下发的状态,用户应在接收到后,把信息保存后尽快返回一个0表示成功接收到状态,不要在回调函数中直接处理信息,以免影响接收的速度;回调函数的定义请参见FuncDef.h中的定义;
分享到:
相关推荐
总的来说,CMPP2.0短信接口开发涉及到网络编程、协议解析等多个技术领域,C#作为一种强大的.NET开发语言,提供了丰富的类库支持,使得开发者能够方便地实现与移动运营商的接口对接,实现高效、稳定的短信服务。
中国移动短信CMPP 2.0协议API是一种专用于短信服务的通信协议,广泛应用于移动通信领域,特别是企业级应用,如验证码发送、信息推送等。该协议基于TCP/IP,为服务提供商提供了高效、稳定且安全的短信发送和接收功能...
中国移动短信网关模拟器是为开发者和测试人员提供的一种工具,它能够模拟中国移动的CMPP2.0协议,用于测试和验证短信应用的正确性和效率。CMPP2.0(China Mobile Short Message Peer-to-Peer Protocol version 2.0)...
CMPP(China Mobile Peer-to-Peer)是一种由中国移动制定的通信协议,主要用于短信服务,包括短信提交、查询、接收和报告等操作。CMPP 2.0是该协议的一个版本,它在CMPP 1.0的基础上进行了优化和增强,提高了系统的...
3. **协议解析**:设计CMPP2.0协议的解码器(Decoder)和编码器(Encoder),将原始的字节流转换为业务对象,反之亦然。这通常涉及到对CMPP协议报文结构的深入理解,包括报文头、消息ID、业务类型等字段。 4. **...
CMPP2.0(China Mobile Peer-to-Peer Protocol Version 2.0)是中国移动通信集团设计...在使用过程中,深入理解CMPP2.0协议,参照提供的文档和示例,以及适时访问开发者网站获取最新信息,都是确保成功应用的关键步骤。
包含接口API与测试工程: 主目录下是详细使用手册.接口文件放在API文件夹中. Demo Project中包含两个示例工程. 一个是模拟网关的源码--“CMPPGateway” 一个是SP连接网关的示例代码--“SPClient”
CMPP(China Mobile Peer-to-Peer)协议是中国移动通信公司为SP(Service Provider)提供的一种基于TCP/IP协议的通信协议,用于实现SP与移动运营商之间的数据传输,主要包括短信、彩信、WAP Push等业务。C#是微软...
CMPP2.0和CMPP3.0是该协议的不同版本,分别对应不同的功能需求和性能优化。 CMPP2.0是早期的版本,它支持基本的短信业务,如点对点短信、群发短信、短信状态报告等。CMPP2.0协议主要由以下几个关键部分组成: 1. ...
**CMPP2.0(China Mobile Packet Protocol)**是中国移动制定的一套用于移动互联网短信业务的标准协议,旨在规范SP(Service Provider,服务提供商)与运营商之间短消息业务的交互流程。此手册详细介绍了一款基于...
CMPP2.0是China Mobile Packet Protocol的2.0版本,是中国移动为了高效地处理大量短信业务而设计的一种协议。这个协议主要用于SP(Service Provider)与SMSC(Short Message Service Center,短信服务中心)之间的...
- 定期更新工具,以适应中国移动可能对CMPP2协议的更新和优化。 总的来说,这个压缩包提供的CMPP2客户端和服务端测试工具对于理解和调试CMPP2协议非常有帮助,无论是新手还是经验丰富的开发者,都能从中受益,提高...
CMPP(China Mobile Short Message Peer-to-Peer Protocol)是中国移动制定的一种高效、可靠的点对点短消息传输协议,它分为CMPP2.0和CMPP3.0两个版本,分别对应不同的功能需求和性能优化。 在描述中提到,该API...
总之,这个Java版的CMPP2.0实现为开发者提供了一个快速接入中国移动短信服务的平台,通过理解并运用此项目,开发者可以深入理解短信网关协议的工作原理,并能有效地集成到自己的应用系统中,实现短信的发送和接收...
中国移动短信网关CMPP(China Mobile Packet Protocol)3.0是一种专用于移动通信领域的协议,主要用于短信服务,包括发送、接收、查询等操作。华为作为知名的电信设备供应商,提供了对应的Java API来帮助开发者便捷...
在这个项目中,开发者使用C#语言实现了CMPP2.0协议的客户端,使得开发者可以通过编程接口(API)方便地向中国移动的短信网关发送和接收短信。这个客户端可能包含以下关键组件: 1. **连接管理模块**:负责建立和...
在这个项目中,开发者使用VC6.0来实现CMPP2.0协议,创建了一个接口,使得SP可以通过这个接口与移动运营商的短消息网关进行交互,简化了接入过程,减少了开发的复杂性。 在提供的压缩包文件中,我们可以找到以下几个...
1. **协议仿真**:CMPP20模拟网关能够精确地模拟中国移动的CMPP2.0服务器行为,包括连接管理、消息传输、错误处理等,帮助开发者在本地环境中进行功能测试和性能优化。 2. **消息模拟**:支持发送和接收各种CMPP2.0...
在CMPP2.0中,短信被分为普通短信和长短信两类。长短信是指超过70个字符的短信,需要通过特殊编码方式拆分成多条短消息发送。尽管此平台目前仅支持普通短信,但开发者可以根据需求自行修改源码来实现长短信功能。 ...
该API遵循《中国移动通讯信息资源站实体与互联网短消息网关接口协议v2.0》,旨在帮助服务提供商更便捷地接入中国移动的短信网关系统,从而提供短信服务。 **1.2 参考文档** - **《中国移动通讯信息资源站实体与...