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

📄 platformdlg.cpp

📁 用Visual C++开发的联通短信平台
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	delete[] pSrc;

	CONNECT.head.nCommandID = htonl(CMPP_CONNECT);
	CONNECT.head.nSequenceID = htonl(msg.nRecID - 1);
	CONNECT.head.nTotalLen = htonl(sizeof(CONNECT));

	Write2RichEditAndLog("MT正在登录短信网关.........");
	//CMPP协议连接网关
	if (SOCKET_ERROR == send(mtsocket,(char*)&CONNECT,sizeof(CONNECT), 0))
	{
		CString err;
		err.Format("发送MT登录消息出错,错误代码是%u", WSAGetLastError());
		Write2RichEditAndLog(err);

		csSubmitNum.Lock();
		nSubmitNum = 0;
		csSubmitNum.Unlock();

		return FALSE;
	}
	while (pMTRecThread->ResumeThread()!=0);//开始MTRec线程函数
	return TRUE;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////
//                                          MO登录移动网关                                           //
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CMPPMOConnectISMG()
{
	using namespace CMPP;
	csMT.Lock();
	int nMTSize = MTQueue.size();
	csMT.Unlock();
	

	struct sockaddr_in dest_addr; /* 目的地址*/ 
	//创建mosocket
	mosocket[0] = socket(AF_INET, SOCK_STREAM, 0); 
	if (INVALID_SOCKET == mosocket[0])/* 错误检查 */ 
	{
		Write2RichEditAndLog("初始化MO SOCKET失败");
		return FALSE;
	}

	//设置MO连接接收超时时间
	int timeout = 1000 * 60 * 2;
	int err;
	err = setsockopt( 
		mosocket[0], 
		SOL_SOCKET, 
		SO_RCVTIMEO, 
		(char *)&timeout, 
		sizeof(timeout));

	if (err != NO_ERROR) 
	{
		Write2RichEditAndLog("设置MO SOCKET接收超时失败");
		return FALSE;
	}

	dest_addr.sin_family = AF_INET; /* host byte order */ 
	csConfig.Lock();
	dest_addr.sin_port = htons(g_config.MOPort); /* short, network byte order */ 
	dest_addr.sin_addr.s_addr = inet_addr(g_config.ISMGip); 
	csConfig.Unlock();
	memset(dest_addr.sin_zero, 0, 8);

	//TCP连接网关
	if (SOCKET_ERROR == connect(mosocket[0], (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)))
	{
		Write2RichEditAndLog("连接短信网关失败,请检查配置文件是否正确");
		return FALSE;
	}


	//连接上之后向ISMG发送CONNECT消息
	struct tagCONNECT
	{
		MessageHeader head;
		SConnect body;
	}CONNECT;
	//填充connect结构
	csConfig.Lock();
	memcpy(CONNECT.body.sSrcAddr, g_config.SPID.GetBuffer(6), 6);
	g_config.SPID.ReleaseBuffer();
	csConfig.Unlock();
	CONNECT.body.nTimeStamp = htonl(GenTimeData());
	CONNECT.body.cVersion = 1;	//MO连接

	//计算AuthenticatorSource
	MD5 md;
	csConfig.Lock();
	u_char *pSrc = new u_char[6 + 9 + g_config.SPLoginPwd.GetLength() + 10];

	memcpy(pSrc, g_config.SPID.GetBuffer(6), g_config.SPID.GetLength());
	g_config.SPID.ReleaseBuffer();

	memcpy(pSrc + + 6 + 9, g_config.SPLoginPwd.GetBuffer(8), g_config.SPLoginPwd.GetLength());
	g_config.SPLoginPwd.ReleaseBuffer();
	csConfig.Unlock();
	CString time;
	time.Format("%d", GenTimeData());
	while (time.GetLength() < 10)
		time = "0" + time;
	csConfig.Lock();
	memcpy(pSrc + 6 + 9 + g_config.SPLoginPwd.GetLength(), time.GetBuffer(10), 10);
	csConfig.Unlock();
	time.ReleaseBuffer();
	memset(pSrc + 6, 0, 9);
	
	//计算MD5
	csConfig.Lock();
	md.update(pSrc, 6 + 9 + g_config.SPLoginPwd.GetLength() + 10);
	csConfig.Unlock();
	md.finalize();
	unsigned char pDest[16];
	md.raw_digest(pDest);
	memcpy(CONNECT.body.sAuthSp, pDest, 16);
	delete[] pSrc;

	CONNECT.head.nCommandID = htonl(CMPP_CONNECT);
	CONNECT.head.nSequenceID = htonl(0);
	CONNECT.head.nTotalLen = htonl(sizeof(CONNECT));
	
	Write2RichEditAndLog("MO正在登录短信网关.........");
	//CMPP协议登录网关
	if (SOCKET_ERROR == send(mosocket[0],(char*)&CONNECT,sizeof(CONNECT), 0))
	{
		CString err;
		err.Format("发送MO登录消息出错,错误代码是%u", WSAGetLastError());
		Write2RichEditAndLog(err);

		return FALSE;
	}

	return TRUE;
}



////////////////////////////////////////////////////////////////////////////////////////////////
//                                    CMPPMT线程函数                                          //
////////////////////////////////////////////////////////////////////////////////////////////////
UINT CMPPMTThread(LPVOID pParam)
{
	using namespace CMPP;

	CoInitialize(NULL);
	IsMTConnected = FALSE;

	//////////////////////////连接ISMG/////////////////////////////////////////////////

	BOOL nResult = FALSE;
	if (!IsMTConnected)	//如果没有连接上
		nResult = CMPPMTConnectISMG();

	while (!nResult)
	{
		Sleep(2000);
		nResult = CMPPMTConnectISMG();
	}
	while (!IsMTConnected) //等待MT接收线程返回登录成功消息
		Sleep(1);

	
	struct tagSUBMIT
	{
		MessageHeader head;
		SSubmit body;
	}Submit;

	_ConnectionPtr pCon1 = NULL;
	/////////////////////////////连接数据库//////////////////////////////////////
	csConfig.Lock();
	CString strCon = "Provider=SQLOLEDB; Server=";
	strCon = strCon + g_config.DBServer;
	strCon = strCon + "; Database=";
	strCon = strCon + g_config.Database;
	strCon = strCon + "; uid=";
	strCon = strCon + g_config.DBUser;
	strCon = strCon + "; pwd=";
	strCon = strCon + g_config.DBPwd;
	csConfig.Unlock();
	try
	{
		pCon1 = NULL;
		HRESULT hr = pCon1.CreateInstance(__uuidof(Connection));
		if (FAILED(hr))
		{
			::MessageBox(NULL,"连接数据库失败","连接数据库失败",MB_OK | MB_ICONWARNING);
			return TRUE;
		}
		pCon1->Open(strCon.AllocSysString(),"", "", adConnectUnspecified);
	}
	catch (_com_error &e) 
	{
		::MessageBox(NULL,e.Description(),"连接数据库失败",MB_OK | MB_ICONWARNING);
	}	


	for(;1;)
	{
		csMT.Lock();
		int nMTSize = MTQueue.size();
		csMT.Unlock();
		if (nMTSize == 0) //检查MTQueue是否为空
		{
			Sleep(100);
			continue;
		}
		/////////////////////////////从消息队列中取出消息并发送//////////////////////////////////
		csMT.Lock();
		CMessage msg = MTQueue.front();
		csMT.Unlock();
		
		//////////////////////////////////////////发送ACTIVETEST维持连接状态/////////////////////////////////////////
		CString Mobile(msg.sMobileNum);
		if (Mobile == "MTActiveTest")
		{
			MessageHeader head;
			head.nCommandID = htonl(CMPP_ACTIVE_TEST);
			head.nSequenceID = htonl(msg.nRecID);
			head.nTotalLen = htonl(sizeof(MessageHeader));

			int nResult = send(mtsocket, (char*)&head, sizeof(MessageHeader), 0);
			if (SOCKET_ERROR == nResult || 0 == nResult)
			{
				Write2RichEditAndLog("发送CMPP_ACTIVE_TEST消息时MT和短信网关的连接已经断开");

				csSubmitNum.Lock();
				nSubmitNum = 0;
				csSubmitNum.Unlock();

				CloseSocket(mtsocket);
				IsMTConnected = FALSE;
				//////////////////////////连接ISMG///////////////////////////////////////////////////
				nResult = FALSE;
				while (!nResult)
				{
					Sleep(2000);
					nResult = CMPPMTConnectISMG();		
				}
				int nStep = 0;
				while (!IsMTConnected)
				{
					Sleep(10);
					nStep += 1;
					if (nStep > 200)	//如果等待IsMTConnected超时,则关闭连接并继续
					{
						CloseSocket(mtsocket);
						break;
					}
				}
				continue;
			}
			//////////////////////////////////////删除队列头//////////////////////////////////////////
			csMT.Lock();
			MTQueue.pop_front();
			csMT.Unlock();
			continue;

		}

		//填充SUBMIT结构
		Submit.head.nCommandID = htonl(CMPP_SUBMIT);
		Submit.head.nSequenceID = htonl(msg.nRecID);									//在SUBMIT结构里面nSequenceID为消息的nRecID

		Submit.body.cDestUsrTl = 1;														//终端用户数量
		Submit.body.cFeeUserType = 3;													//计费用户类型,对谁计费参见Fee_terminal_Id字段
		memset(Submit.body.sFeeTermId, 0, 21);
		memcpy(Submit.body.sFeeTermId, msg.sChargeNumber, strlen(msg.sChargeNumber));	//被计费用户的号码
		Submit.body.cMsgFmt = msg.sMsgFmt;												//信息格式
		Submit.body.cMsgLevel = 7;														//信息级别
		Submit.body.cPkNumber = 1;														//相同Msg_Id的信息序号,从1开始
		Submit.body.cPkTotal = 1;														//相同Msg_Id的信息总条数,从1开始
		Submit.body.cTpPid = 0; 
		Submit.body.cTpUdhi = 0; 
		memset(Submit.body.sAtTime, 0, 17);												//定时发送时间
		memset(Submit.body.sDstTermId, 0, 21);
		memcpy(Submit.body.sDstTermId, msg.sMobileNum, strlen(msg.sMobileNum));			//目的手机号码

		if (msg.sFeeType > 5 && msg.sFeeType < 10)										//设置成免费信息
		{
			msg.sFeeType = 1;
			memcpy(msg.sFeeCode, "000000", 6);
		}
		if (msg.sFeeType == 10)															//此SUBMIT用于产生包月话单
		{
			memcpy(Submit.body.sFeeType, "03", 2);										//资费类别
			Submit.body.cRegister = 2;													//产生SMC话单
		}
		else
		{
			CString feetype;
			feetype.Format("0%d", msg.sFeeType);
			memcpy(Submit.body.sFeeType, feetype, 2);									//资费类别
			Submit.body.cRegister = 1;													//需要返回状态确认报告
		}

		memcpy(Submit.body.sFeeCode, msg.sFeeCode, 6);									//资费代码
		memset(Submit.body.sMsgId, 0, 8);												//信息ID,此处全部置零
		csConfig.Lock();
		memcpy(Submit.body.sMsgSrc, g_config.SPID, 6);									//信息来源
		csConfig.Unlock();
		memset(Submit.body.sServiceId, 0, 10);
		memcpy(Submit.body.sServiceId, msg.sServiceID, strlen(msg.sServiceID));			//业务代码
		memset(Submit.body.sSrcTermId, 0, 21);
		memcpy(Submit.body.sSrcTermId, msg.sSrcMobile, strlen(msg.sSrcMobile));			//源号码,号码后面补二进制0
		memset(Submit.body.sValidTime, 0, 17); 
		Submit.body.ucMsgLen = strlen(msg.sMsg);										//信息长度
		Submit.head.nTotalLen = htonl(sizeof(Submit) + strlen(msg.sMsg) + 8);

		char *pBuf = NULL;
		pBuf = new char[sizeof(Submit) + strlen(msg.sMsg) + 8];
		memcpy(pBuf, &Submit, sizeof(Submit));
		memcpy(pBuf + sizeof(Submit), msg.sMsg, strlen(msg.sMsg));						//信息内容
		memset(pBuf + sizeof(Submit) + strlen(msg.sMsg), 0, 8);

		//得到当前的滑动窗口值
		csSubmitNum.Lock();
		short num = nSubmitNum;
		csSubmitNum.Unlock();

		if (num >= maxwindow) //如果发送SUBMIT而没有应答的数量大于最大滑动窗口,则挂起100MS返回
		{
			Sleep(100);
			csSubmitNum.Lock();
			num = nSubmitNum;
			csSubmitNum.Unlock();
			continue;
		}

		//发送SUBMIT消息

		//添加到MTUnsendQueue队列
		CTime t = CTime::GetCurrentTime();
		CString time = t.Format("%y%m%d%H%M%S");
		strcpy(msg.sDatetime, time);
		
		//消息内的发送次数+1
		msg.nSendCount ++;
		csMTUsend.Lock();
		MTUnsendQueue.push_back(msg);
		csMTUsend.Unlock();

		//删除MTQueue队列头
		csMT.Lock();
		MTQueue.pop_front();
		csMT.Unlock();

		int nResult = send(mtsocket, pBuf, sizeof(Submit) + strlen(msg.sMsg) + 8, 0);
		if (SOCKET_ERROR == nResult || 0 == nResult)
		{
			if(pBuf != NULL)
			{
				delete[] pBuf;
				pBuf = NULL;
			}
			Write2RichEditAndLog("发送SUBMIT消息时MT和短信网关的连接已经断开");
			csSubmitNum.Lock();
			nSubmitNum = 0;
			csSubmitNum.Unlock();

			CloseSocket(mtsocket);
			IsMTConnected = FALSE;

			//////////////////////////连接网关//////////////////////////////////////
			nResult = FALSE;
			while (!nResult)
			{
				Sleep(2000);
				nResult = CMPPMTConnectISMG();		
			}
			int nStep = 0;
			while (!IsMTConnected)
			{
				Sleep(10);
				nStep += 1;
				if (nStep > 200)	//如果等待IsMTConnected超时,则关闭连接并继续
				{
					CloseSocket(mtsocket);
					break;
				}
			}
			continue;
		}


		if (pBuf != NULL)
		{
			delete[] pBuf;
			pBuf = NULL;
		}
		//滑动窗口加1
		csSubmitNum.Lock();
		nSubmitNum ++;
		csSubmitNum.Unlock();
	
		Sleep(msgsendinterval);//等待msgsendinterval毫秒

	}

	CoUninitialize();
	return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////
//                                   SGIPMT线程函数                                           //
////////////////////////////////////////////////////////////////////////////////////////////////
UINT SGIPMTThread(LPVOID pParam)

⌨️ 快捷键说明

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