📄 sgipapi.h
字号:
/**
* 文件名称: SGIP.h
* 实现功能: 中国联通短消息业务联网协议1.2版(sgip1.2 最新0213升级版)头文件.
* 文件作者: PrinceToad(范圣刚,北京风起水流软件工作室)
* 软件声明: 免费提供SP短消息网关开发接口库下载使用(CMPP3.0,SGIP1.2,CMPP2.0)
* 联系方式:
* Homepage:Http://www.zealware.com
* MSN: princetoad2003@hotmail.com
* OICQ: 50506711
* Email: princetoad@gmail.com
* PhoneNo:010-13901168061
* 软件版本:
* Revision V1.70 06/22/2007
* 1.采用类封装方式实现SGIPAPI.
* 2.去掉了MFC类库的使用.
*
* V1.61 May.07.06
* 1.修正了上行连接线程安全的一个Bug.
*
* V1.6 Mar.25.06
* 1.加入了是否对网关登录SP的用户名口令进行验证的配置和参数。
* 2.加入了对网关连接SP的最大连接数进行配置的参数。
* 3.增加了输出调试日志的接口。
* 4.增加了允许设定线城池的工作线程数的参数配置。
* 5.支持输出SMG到网关的连接的连接数,SOCKET句柄,和远程端口(可以在外部关闭网关连接).
* 6.回调函数返回值改为int.(允许在回调函数中返回值)
* 7.修正了一些BUG.
*
* V1.42 Jul.30.04
* 1.不对SUBMIT消息的MSGCONTENT长度作限制,原来的长度限制160,现在只要整个消息包不超
* 过2K就可以.
*
* V1.41 Jul.30.04
* 1.加入了对MO连接远程服务器IP地址的判断,防止非法攻击!
* 2.彻底修正了MT断开重连,再发消息的Bug,MTRESP不会再返回255的错误.
*
* V1.4 Jul.19.04
* 1.修正了一个返回函数指针错误的问题。.(Special Thanks mate.)
* 2.增加了了程序启动模式,在Start函数里,当指定nLocalPort = -1时,不建立本地监听,只执行发送模块;
* 当指定nPeerPort = -1时,只进行监听,接收MO消息,不建立同网关的连接.
* V1.36 Jun.07.04
* 1.修改了多连接分配时候的一个Bug,该Bug能够导致在流量比较大的时候丢失MT消息。
* 2.去除了除试用版过期的以外的其他消息提示对话框。
* 3.Start函数里面加了一个参数fOutputDebugInfo,用来指示是否输出调试信息,
* 如果输出的话,DLL会在当前目录下建立一个文本文件debug.log,输出DLL的相关信息,
* 用作调试,出现错误情况时可以查看该文件。
* V1.34 Apr.13.04
* 1.修改了接收超时导致丢失MO消息的问题。
* V1.33 Mar.30.04
* 1.根据联通的最新修改,LinkId字段不作为两个整数来处理,直接作为8字节的字符串处理。
* V1.32 Mar.23.04
* 1.修改了连接中断后,重连的一个Bug.
* V1.3 Mar.07.04
* 1.修改了MT消息的发送方式,发送方式由原来的短连接(即一条消息建立一次连接)改为
* 现在的长连接,提高了发送效率,减轻了网关负担。
* 2.Start()函数增加了一个参数,允许用户自定义同网关建立的连接数,默认是3
* (网关连接数最好不要超过数值N, N = CPU个数*2 + 2)。
* V1.28 Feb.26.04
* 1.还是根据《SGIPV1.2协议适应性修改0120(SP分册)》作了相应修改。
* 2.根据协议变更,修改了Submit, Deliver, deliverstr结构体的定义,增加或者修改了Reserved,linkid字段。
* 3.修改了MO,MT消息收发函数.
* V1.27 Feb.16.04
* 1.根据《SGIPV1.2协议适应性修改0120(SP分册)》作了相应修改.
* V1.26 Jan.27.04
* 1.修正了MTError时,mt_err结构提没有带回DateTime的错误。
* V1.25 Dec.22.03
* 1.在Submit函数中返回了submit消息包序列号中的时间戳(与Reponse和Report中的时间戳是对应的),
* 通过时间戳与序列号的结合彻底解决了序列号唯一对应的问题(哪怕是系统重新启动).
*
* V1.24 Dec.04.03
* 1.更正了在接收消息包时未给ReportStr中的nSubmitSeqId字段赋值的错误。
* 2.更正了MTError返回时不能带回序列号的问题.
* 3.在ReportStr字段中加入新的字段unsigned int nSubmitDateTime,用于保存更加详细的Report内容.
*
* V1.23 Nov.25.03
* 1.MTErrorStr和MTRespStr两个消息结构中增加一个sgipg_submit字段,用于返回其对应的SUBMIT消
* 息包,即这两个消息是由哪个SUBMIT包返回的,原因是SubmitResp包中并未包含开发者可能用到的必要信
* 息(如手机号码等,虽然这些信息在Report消息里面包含的比较全面)。
*
* V1.21 Nov.08.03
* 1.增加了函数CSgip::AddUserNumber(),可以方便地进行短消息群发.
* 2.增加了函数CSgip::GetSubmitSeqId(),功能是获得下一条submit消息的序列号.
* 在调用Submit()函数前调用可以提前获得将要发送的submit消息的序列号,类推的话,
* 下一条submit消息的序列号将在上一条消息序列号的基础上加3.这样的话就可以提前给submit消息编号,
* 然后等待submit_resp消息的到来。
* 3.CSgip::Submit()函数的原型由CSgip::Submit(sgipg_submit ss)变为
* CSgip::Submit(sgipg_submit ss, unsigned int &nSeq),输出参数nSeq的作用是返回submit消息的序列号.
*
* V1.2 Sep.11.03
*
*/
#ifndef _SMAL_SGIP_API_H
#define _SMAL_SGIP_API_H
#include <smal.h>
#include <common/threadpool.h>
#include <common/const.h>
#include <sgip/sgip_message.h>
#include <list>
using namespace std;
class CSgip;
///
/// SGIP JOB类
///
//##ModelId=46B5D42E028C
class CJobSgip : public IJobDesc {
public:
//##ModelId=46B5D42E0297
CJobSgip(SOCKET &hSocket, CSgip* sgip, unsigned remoteport);
//##ModelId=46B5D42E02AA
CJobSgip(sgipg_submit pss, CSgip* sgip, unsigned int nSeq, unsigned int nDateTime);
//##ModelId=46B5D42E02B4
~CJobSgip();
//##ModelId=46B5D42E02BE
void RecvMOProc();
//##ModelId=46B5D42E02C8
void SendMTProc();
//##ModelId=46B5D42E02D2
int nType;
private:
//##ModelId=46B5D42E02DD
sgip_conn sp_conn;
//##ModelId=46B5D42E02E7
CSgip* m_sgip;
//##ModelId=46B5D42E02F1
sgipg_submit ss;
//##ModelId=46B5D42E02FB
unsigned m_nSeq;
//##ModelId=46B5D42E0305
unsigned m_nDateTime;
};
///
/// SGIP WORK类
///
//##ModelId=46B5D42E0318
class CWorkerSgip : public IWorker {
//##ModelId=46B5D42E0322
virtual void ProcessJob( IJobDesc* pJobDesc );
};
///
/// 网关连接信息
///
//##ModelId=46B5D42E0336
class ConnInfo {
public:
//##ModelId=46B5D42E0340
ConnInfo() {
socketHandle = 0;
port = 0;
memset(connectedTime, 0, MAX_PATH);
}
//##ModelId=46B5D42E0341
ConnInfo(
unsigned _socketHandle,
unsigned _port,
const char * _connectedTime
)
{
socketHandle = _socketHandle;
port = _port;
#if defined(_MSC_VER) && _MSC_VER >= 1400
strcpy_s(connectedTime, MAX_PATH, _connectedTime);
#else
strcpy(connectedTime, _connectedTime);
#endif
//strcpy(connectedTime, _connectedTime);
}
//##ModelId=46B5D42E034E
unsigned socketHandle; ///< 网关到SP的SOCKET句柄
//##ModelId=46B5D42E0355
unsigned port; ///< 网关的远程端口
//##ModelId=46B5D42E035E
char connectedTime[MAX_PATH]; ///< 网关到SP的连接连接时间
};
//##ModelId=46B5D42E0368
typedef std::list<ConnInfo> cList;
/// SGIP网关实现类
//##ModelId=46B5D42F003F
class /*SGIP_API*/ CSgip{
friend class CJobSgip;
public:
/**@name Construction */
//@{
///
/// 构造函数,初始化WinSock,初始化变量值
///
//##ModelId=46B5D42F0049
CSgip();
///
/// 析构函数,释放WinSock
///
//##ModelId=46B5D42F005D
virtual ~CSgip();
static CSgip* getInstance();
//@}
/**@name Main Functions */
//@{
/**
* SGIPAPI启动主函数
* 在这个函数里面启动本地监听,连接网关,和启动线城池。
* 注意:
* 1.在调用Start函数启动后,如果想重新调用Start函数,
* 必须首先调用Release函数释放资源才能重新调用Start函数,否则会调用失败。
* 2.可以通过设定nLocalPort=-1,或nPeerPort=-1实现收发分离功能。
*
* @param sLocalIP SGIP本地监听地址
* @param nLocalPort SGIP的本地监听端口(注意:如果设为-1则不启动本地监听,即不接收网关的连接和消息,只启用发送功能)
* @param sPeerIP 联通网关地址
* @param nPeerPort 联通网关端口(注意:如果设为-1,则不连接网关,即不执行发送功能,可以只接收MO消息)
* @param sLoginName 登录联通网关的用户名
* @param sLoginPwd 登录联通网关的口令
* @param nConnType 登录网关的连接类型(按照协议规定,应该一直是1。<1:SP向SMG建立的连接,用于发送命令>)
* @param sSrcNum 源节点编号(SP的编号规则:3AAAAQQQQQ AAAA表示四位长途区号,QQQQQ表示5位企业代码。详见协议3.3)
* @param nConnCount 同网关建立的发送连接数
* @param sPeerName 网关登录SP的用户名(如果用户名或者口令为空的话,则不对网关连接进行用户名口令鉴权)
* @param sPeerPwd 网关登录SP的口令
* @param nMaxSmgConn 允许的网关到SP的最大连接数
* @param nMinWorkThreadsCount 线程池的最小线程数(即初始线程数,建议为CPU个数*2 + 2)
* @param nMaxWorkThreadsCount 线程池的最大线程数(建议为CPU个数*2 + 6,线程池会根据忙碌状态在此范围内自动调整)
*
* @return 0:成功; -1:失败
*/
//##ModelId=46B5D42F0071
int Start(
const char *sLocalIP,
int nLocalPort,
const char *sPeerIP,
int nPeerPort,
const char *sLoginName,
const char *sLoginPwd,
int nConnType,
const char *sSrcNum,
int nConnCount = 3,
const char *sPeerName = NULL,
const char *sPeerPwd = NULL,
unsigned nMaxSmgConn = 16,
unsigned nMinWorkThreadsCount = 4,
unsigned nMaxWorkThreadsCount = 8
);
///
/// 断开连接,停止线程池,释放资源
///
//##ModelId=46B5D42F0099
void Release(
BOOL forceRelease = FALSE ///< 如果Start没有启动成功,是否强制释放
);
///
/// 提交MT消息
/// nDatetime(submit包的时间戳,序列号中的第二个字段),
/// 与nSeq结合能够做到唯一标识一条submit消息(即使系统重新启动,nSeq重新归零).
///
//##ModelId=46B5D42F00A3
void Submit(
sgipg_submit ss, ///< Submit消息包
unsigned &nSeq, ///< 该消息包的序列号中的序列号
unsigned &nDateTime ///< 该消息包的序列号中的时间戳
);
/////
///// 支持群发的设置目的号码的函数.
///// sUserNumber可以是单个的手机号码,或者以逗号,中划线隔开的多个号码.
///// 可以是以下几种类型之一,例如:"8613312345678",或"8613312345678,86133123456789",
///// 或"8613312345670-8613312345679",或"8613312345670,8613312345675-8613312345689",或"8613012345678,8613012345679-8613012345688,8613312312312"。
/////
//int AddUserNumber(
// sgipg_submit* ss, ///< 要群发的消息包
// const char* sUserNumber ///< 要增加的群发手机号
//);
///
/// 得到下一条要发submit消息的序列号
///
//##ModelId=46B5D42F00AF
unsigned int GetSubmitSeqId();
///
/// 得到当前网关到SP的连接信息
///
//##ModelId=46B5D42F00B0
void GetSmgConnInfo(
cList & _connList
) {
_connList = connList;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -