📄 platformdlg.cpp
字号:
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 + -