⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sgipapi.h

📁 看到联通的接口协议的dll没
💻 H
字号:
//*************************************************************************************************************//	文件名称:	SGIP.h//	实现功能:	中国联通短消息业务联网协议1.2版(sgip1.2 最新0213升级版)头文件.//	文件作者:	PrinceToad(范圣刚,北京风起水流软件工作室)//	软件声明:	免费提供SP短消息网关开发接口库下载使用(CMPP3.0,SGIP1.2,CMPP2.0)


//				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
//
//
//**************************************************************************************************************




/*

     kenlistian 添加cpp部分,没测试过,仅供学习参考

*/
#ifndef _SMAL_SGIP_API_H
#define _SMAL_SGIP_API_H

#include "smal.h"
#include "threadpool.h"
#include "const.h"
#include "sgip_message.h"

#include <list>
using namespace std;


#ifdef SGIP_IMPORT
#define	SGIP_API __declspec(dllimport)
#else
#define	SGIP_API __declspec(dllexport)
#endif



#pragma warning(disable : 4251)
#pragma warning(disable : 4018)

class CSgip;


/*****************************************
 
   SGIP JOB类 
  remoteport记录远程网关连接过来的端口号
    
  下行线程(submit)
     发送时应该创建工作,发送完就结束工作。
	 其中submit后处理response.处理完后结束工作

  上行线程(deliver)
     处于不断接受状态,有包来时处理,并response,
	 
	 该线程处于论询recv状态,当有deliver时,打包递出事件,同时需repose,
	 当网关unbind,响应unbind_resp后关闭连接.

     在accept后,开始上行工作,当网关unbind后处理完结束工作.
	 

*/
class CJobSgip : public IJobDesc 
{
public:
	CJobSgip(SOCKET &hSocket, CSgip* sgip, unsigned remoteport);      //网关连接sp
	CJobSgip(sgipg_submit pss, CSgip* sgip, unsigned int nSeq, unsigned int nDateTime);  //sp发送信息到网关
	~CJobSgip();

	void	RecvMOProc();			//接受上行消息
	void	SendMTProc();			//下行发送消息
	int		nType;					//类型. 估计 ntype = 1 是 上行,= 2是下行
private:
	sgip_conn		sp_conn;		//网关连接sp信息结构体
	CSgip*			m_sgip;			
	sgipg_submit	ss;				//发送结构体
	unsigned		m_nSeq;
	unsigned		m_nDateTime;
};


//SGIP WORK类
class CWorkerSgip : public IWorker 
{
public:
	virtual void ProcessJob( IJobDesc* pJobDesc );
};


/*   
   网关连接sp信息
*/
class ConnInfo {
public:
	ConnInfo() {
		socketHandle	= 0;
		port					= 0;
		connectedTime = _T("");
	}
	
	ConnInfo(unsigned	_socketHandle, unsigned	_port,	CString	_connectedTime) 
	{
		socketHandle	= _socketHandle;
		port			= _port;
		connectedTime = _connectedTime;
	}
	unsigned	socketHandle;		// 网关到SP的SOCKET句柄
	unsigned	port;				// 网关的远程端口
	CString		connectedTime;		// 网关到SP的连接连接时间
};
typedef std::list<ConnInfo>		cList;


/*	
  SGIP协议封装类    
*/
class SGIP_API CSgip{
	friend class CJobSgip;
public:
	CSgip();              //	初始化WinSock,初始化变量值		
	virtual ~CSgip();     //	释放WinSock	
	
	int Start(
		char			*sLocalIP,         
		int				nLocalPort,
		char			*sPeerIP, 
		int				nPeerPort, 
		char			*sLoginName, 
		char			*sLoginPwd, 
		int				nConnType, 
		char			*sSrcNum,
		int				nConnCount = 3, 
		char			*sPeerName = NULL,
		char			*sPeerPwd = NULL,
		unsigned	nMaxSmgConn = 16,
		unsigned	nMinWorkThreadsCount = 4,
		unsigned	nMaxWorkThreadsCount = 8
		);

	void Release(BOOL forceRelease = FALSE);
	int AddUserNumber(sgipg_submit* ss,	const char* sUserNumber);   //暂未处理。支持群发的设置目的号码的函数

	// 提交MT消息,nSeq, nDateTime输出参数		
	void Submit(sgipg_submit ss,unsigned &nSeq,unsigned &nDateTime);			
	
	
	// 收到DELIVER上行消息时调用该函数	 
	virtual int	OnDeliver(DeliverStr & deliver)    	{		return 0; 	}	
	// 收到状态报告时调用该函数	 
	virtual int OnReport(ReportStr & report)       	{		return 0; 	}	
	// 收到Submit应答消息时调用此函数	 
	virtual int OnResponse(MTRespStr & response)   	{		return 0; 	}		
	/*
	 发送SUBMIT消息失败时调用该函数 	 
       1:因为连接不上SMG网关系统  
       2:登录网关失败              
       3:包发送失败且超过重发次数    
       4. 超时无应答                   
       5. 消息长度为零               
       6. 没有可用的连接               
    */	
	virtual int OnMTError(MTErrorStr mterror) {			return 0; 	}

	// 获取当前网关到SP的连接列表
	void GetSmgConnInfo(cList & _connList) {		
		_connList = connList; 
		return;		
	}		
	
	//得到网关到SP的连接数	
	unsigned GetSmgConnCount()	{	return (unsigned)connList.size(); }
	
	/*
	  记录日志函数
	*/
	virtual int	 OnLogWrite(const char* pchFmt, ...) {
		char buffer[1024] = "";

		va_list arglist;						
		va_start( arglist, pchFmt );
		_vsnprintf( buffer, 1024, pchFmt, arglist );
		va_end(arglist);

		TRACE(buffer);

		return 0; 
	}


	//提交的SUBMIT消息数 	
	long GetSubmitCount() const 	{	return submitCountTotal;			}
	//发送成功的SUBMIT消息数 	
	long GetSubmitSucceedCount() const	{	return submitSucceedCountTotal;		}
	//得到发送失败的SUBMIT消息数 	
	long GetSubmitFailedCount() const 	{	return submitFailedCountTotal;		}
	//得到失败的SUBMITResponse消息数 	
	long GetRespFailedCount() const	{	return respFailedCountTotal;		}
	//得到成功的SUBMITResponse消息数 	
	long GetRespSucceedCount() const 	{	return respSucceedCountTotal;		}
	//得到收到的Deliver消息数 	
	long GetDeliverCount() const 	{	return deliverCountTotal;		}
	//得到收到的StatusReport消息数 	 
	long GetStatusReportCount() const 	{	return sreportCountTotal;		}
protected:	
	unsigned int GetSubmitSeqId();									 //得到下一条要发submit消息的序列号	

	//递增提交的SUBMIT消息数 	
	long AddSubmitCount() {		return ::InterlockedIncrement((long*)&submitCountTotal);	}
	//递增发送成功的SUBMIT消息数 	
	long AddSubmitSucceedCount() {	return ::InterlockedIncrement((long*)&submitSucceedCountTotal);	}
	//递增发送失败的SUBMIT消息数 	
	long AddSubmitFailedCount() { 	return ::InterlockedIncrement((long*)&submitFailedCountTotal);	}
	//递增失败的SUBMITResponse消息数 	
	long AddRespFailedCount() { 	return ::InterlockedIncrement((long*)&respFailedCountTotal); 	}
	//递增成功的SUBMITResponse消息数 	
	long AddRespSucceedCount() {	return ::InterlockedIncrement((long*)&respSucceedCountTotal);	}
	//递增收到的Deliver消息数 	
	long AddDeliverCount() { 	return ::InterlockedIncrement((long*)&deliverCountTotal);	}
	//递增收到的StatusReport消息数 	
	long AddStatusReportCount() {	return ::InterlockedIncrement((long*)&sreportCountTotal);	}

protected:
	int SubmitFunc(sgipg_submit ss, unsigned int nSeq, unsigned int nDateTime);
private:
	bool LocalListen();										//本地监听
	bool IsValidIPAddr(LPCTSTR sIPAddr);					//是否有效的ip地址
	
	sgip_conn* GetSubmitConn(int &nConnIndex);				//获得submit的连接
	void ChangeStatus(int nConnIndex, bool fBusy);		 	//改变线程池状态

	bool CreateLogFile();					    		    //创建log文件	

	int	 LoginSmg(sgip_conn *pConn);					   	//sp登陆网关
	void LogoutSmg(sgip_conn *pConn);						//sp退出网关	
	bool CreateConn();									    //sp连接网关
	bool ReleaseConn();								

	void AddSmgConn(unsigned socketHandle, unsigned port);    //网关连接sp
	void RemoveSmgConn(unsigned socketHandle);	

	CString GetDateTime();
	unsigned GetMaxSmgConnections()	{	return m_nMaxSmgConn; }   //网关连接sp的最大数目

private:
	static DWORD WINAPI SgipServFunc(LPVOID pParam);    //线程处理部分
	virtual DWORD SgipServProc();                       

	//int	 (*m_PDeliver)(DeliverStr  deliver);
	//int	 (*m_PReport)(ReportStr report);
	//int	 (*m_PResponse)(MTRespStr  response);
	//int	 (*m_PMTError)(MTErrorStr mterror);
	//int	 (*OnLogWrite)(const char* pchFmt, ...);
	CString GetPeerName() {		return m_sPeerName;	}
	CString GetPeerPwd()  {		return m_sPeerPwd;  }

private:	
	BOOL			m_fStarted;					// 是否已经启动
	BOOL			m_fStop;					// 系统停止标志

	CThreadPool	pool;							// 线程池
	CWorkerSgip	m_worker;
	CJobSgip	*m_pJob;

	CString		m_sPeerAddr;					// 网关IP地址
	int			m_nPeerPort;					// 网关端口	
	CString		m_sUserName;					// 登录用户名
	CString		m_sPwd;							// 登录口令
	int			m_nConnType;					// 连接类型
	int			m_nSubmitConn;					// SP到网关连接数
	CString		m_sSrcNum;						// 原节点号码	
	CString		m_sLocalIPAddr;					// 本机地址
	int			m_nLocalPort;					// 本地监听端口
	CString		m_sPeerName;					// 网关登录SP的用户名
	CString		m_sPeerPwd;						// 网关登录SP的口令
	unsigned	m_nMaxSmgConn;					// 允许的网关到SP的最大连接数

	CString		m_sLogPath;						// 日志文件路径
	//BOOL		m_fLogEvent;					// 是否记录系统日志

	unsigned		m_nMinWorkThreadsCount;		// 线程池初始线程数
	unsigned		m_nMaxWorkThreadsCount;		// 允许的线程池最大线程数

	SOCKET			serverSocket;				// 本地监听套接字
	HANDLE			m_hThread;					// 本地监听线程的句柄
	unsigned		m_nCounter;					// 消息的数量

	int				m_nConnIndex;				// 连接索引
	sgip_conn		SubmitConn[MAX_PATH];		// SP到网关连接数组
	CCriticalSection m_arrayCs;					// 队列临界区

	

	CCriticalSection m_listCs;
	cList				connList;				// 网关连接队列   

	long							submitCountTotal;
	long							submitSucceedCountTotal;
	long							submitFailedCountTotal;
	long							respSucceedCountTotal;
	long							respFailedCountTotal;
	long							deliverCountTotal;
	long							sreportCountTotal;
};

#endif // SGIP_API_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -