📄 platformdlg.cpp
字号:
// PlatformDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "Platform.h"
#include "PlatformDlg.h"
#include ".\platformdlg.h"
#include "protocol.h"
#include "config.h"
#include "md5.h"
#include <afxinet.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//引入ADO组件
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
no_namespace rename("EOF", "EndOfFile")
#define MAXMOTHREAD 10 //定义MO最大线程数
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
////////////////////////////////////////////////////////////////////////////////////////////////////
// 定义全局变量 //
////////////////////////////////////////////////////////////////////////////////////////////////////
CCriticalSection csMT, csMO, csLogFile, csSubmitNum, csMSG, cspCon, csConfig, csPostNum, csMTUsend;//定义同步变量
Queue MTQueue, MOQueue, MTUnsendQueue;//定义队列
CConfig g_config;//配置文件对象
short nSubmitNum = 0; //发送SUBMIT而没有应答的数量,当前的滑动窗口
int mtsocket; //MTSOCKET
int mosocket[MAXMOTHREAD]; //MOSOCKET数组
int molistensocket;//SGIP中的监听SOCKET
//定义线程指针
CWinThread *pMTRecThread =NULL;
CWinThread *pMOThread[MAXMOTHREAD];
CWinThread *pMTThread =NULL;
CWinThread *pFillThread =NULL;
CWinThread *pPostThread =NULL;
CWinThread *pMOAcceptThread =NULL;
_ConnectionPtr pConMOThread = NULL;
int maxwindow,msgsendinterval; //定义最大滑动窗口、消息发送间隔
BOOL IsMTConnected; //MT是否连接
BOOL IsMOConnected; //MO是否连接
MsgQueue MSGQueue; //消息队列
struct sockaddr_in mt_dest_addr; /* 目的地址*/
int nPostNum = 0;//POST线程数
MsgQueue ShieldedWords, BlackList;//屏蔽词,黑名单
CStdioFile logfile;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// 产生时间戳 //
//////////////////////////////////////////////////////////////////////////////////////////////////////////
UINT GenTimeData()
{
CTime t = CTime::GetCurrentTime();
return(t.GetMonth() * 100000000 + t.GetDay() * 1000000 + t.GetHour() * 10000 + t.GetMinute() * 100 + t.GetSecond());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// UCS2编码转换成GB编码 //
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void UCS2ToGB(char *pSrc, int nSrcSize/*int byte*/, char *pDest)
{
//对调高低位!把第2个拷贝成第一个,第一个拷贝成第2个
int i=0;
char *temp = new char[nSrcSize];
memset(temp,0,nSrcSize);
while (i < nSrcSize)
{
memcpy(temp + i, pSrc + i + 1, 1);
memcpy(temp + i + 1, pSrc + i, 1);
i = i + 2;
}
char *tt = new char[nSrcSize];
memset(tt, 0, nSrcSize);
//memset(tt,0,1024);
int nSize = WideCharToMultiByte (
CP_ACP, // ANSI 代码页
WC_COMPOSITECHECK, // 检查重音字符
(LPCWSTR)temp, // 原Unicode 串
nSrcSize / 2, // -1 意思是串以0x00结尾
tt, // 目的char字符串
nSrcSize, // 缓冲大小
NULL, // 缺省字符串
NULL); // 忽略这个参数
memcpy(pDest, tt, nSize);
pDest[nSize] = 0;
delete []tt;
delete []temp;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
// 写入显示界面和LOG文件 //
/////////////////////////////////////////////////////////////////////////////////////////////////////
void Write2RichEditAndLog(CString str)
{
////////////////写入RICHEDIT内容////////////////////////////////////////////////
CTime t = CTime::GetCurrentTime();
CString text = t.Format("%Y年%m月%d日%H时%M分%S秒:");
text = text + str ;
csMSG.Lock();
MSGQueue.push_back(text);
csMSG.Unlock();
/////////////////////////////////////写日志文件////////////////////////////////////////////////////////
/* CFileFind filefind;
TRY
{
csLogFile.Lock();
if (!filefind.FindFile(g_config.LogPath))
{
::MessageBox(NULL, g_config.LogPath + _T(",不存在此路径,请检查配置文件"), _T("无法找到路径"), MB_OK | MB_ICONWARNING);
return;
}
if (logfile.GetFilePath() != g_config.LogPath + _T("\\") + t.Format("%Y年%m月%d日") + _T(".log")) //如果到第二天的话,关闭前一天的LOG文件
if(logfile.m_hFile != CFile::hFileNull) //如果文件已经打开则关闭文件
logfile.Close();
if (logfile.m_hFile == CFile::hFileNull) //如果文件没有打开则打开文件
{
logfile.Open(g_config.LogPath + _T("\\") + t.Format("%Y年%m月%d日") + _T(".log"), CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite|CFile::shareDenyNone);
}
logfile.SeekToEnd();
text.Insert(text.GetLength(), 13);
text.Insert(text.GetLength(), 10);
logfile.WriteString(text);
csLogFile.Unlock();
ULONGLONG dwLength = logfile.GetLength();
if (dwLength > 1000 * 1024)
{
CString hour = t.Format("%H%M%S");
CopyFile(logfile.GetFilePath(), logfile.GetFilePath() + hour, FALSE);
if (logfile.m_pStream != NULL)
logfile.Close();
DeleteFile(logfile.GetFilePath());
}
}
CATCH(CFileException ,pEx)
{
CString error;
error.Format(_T("写LOG文件出错,错误代码是:%u"), pEx->m_cause);
if (logfile.m_pStream != NULL)
logfile.Close();
csMSG.Lock();
MSGQueue.push_back(error);
csMSG.Unlock();
}
END_CATCH
*/
}
/*void Write2RichEdit(CString str)
{
////////////////写入RICHEDIT内容////////////////////////////////////////////////
CTime t = CTime::GetCurrentTime();
CString text = t.Format("%Y年%m月%d日%H时%M分%S秒:");
text = text + str ;
csMSG.Lock();
MSGQueue.push_back(text);
csMSG.Unlock();
}*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 关闭SOCKET //
/////////////////////////////////////////////////////////////////////////////////////////////////////////
void CloseSocket(int nSocket)
{
closesocket(nSocket);
if (mtsocket == nSocket)
{
Write2RichEditAndLog(_T("MTRED"));
}
int nMOThread = 0;
while (nMOThread < MAXMOTHREAD)
{
if (mosocket[nMOThread] == nSocket)
{
mosocket[nMOThread] = NULL;
break;
}
nMOThread ++;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// 登录联通网关 //
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL SGIPMTConnectISMG()
{
using namespace SGIP;
CMessage msg;
csMT.Lock();
int nMTSize = MTQueue.size();
csMT.Unlock();
while (nMTSize == 0) //如果MT队列中没有消息,则等待100MS,并循环
{
Sleep(100);
csMT.Lock();
nMTSize = MTQueue.size();
csMT.Unlock();
}
csMT.Lock();
msg = MTQueue.front(); //得到队列中第一个消息
csMT.Unlock();
//创建mtsocket
mtsocket = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == mtsocket) /* 错误检查 */
{
Write2RichEditAndLog(_T("初始化MO SOCKET失败"));
return FALSE;
}
mt_dest_addr.sin_family = AF_INET; /* host byte order */
csConfig.Lock();
mt_dest_addr.sin_port = htons(g_config.MTPort); /* short, network byte order */
mt_dest_addr.sin_addr.s_addr = inet_addr(g_config.ISMGip);
csConfig.Unlock();
memset(mt_dest_addr.sin_zero, 0, 8);
//TCP协议连接网关
int nResult = connect(mtsocket, (struct sockaddr*)&mt_dest_addr, sizeof(struct sockaddr));
if (SOCKET_ERROR == nResult)
{
Write2RichEditAndLog(_T("连接短信网关失败,请检查网关配置是否正确"));
return FALSE;
}
struct tagBIND
{
MessageHeader head;
SBind body;
}BIND;
csConfig.Lock();
BIND.head.nSeqNumber[0] = htonl(g_config.SPNODEID); //源节点编号
csConfig.Unlock();
BIND.head.nSeqNumber[1] = htonl(GenTimeData()); //时间戳
BIND.head.nSeqNumber[2] = htonl(msg.nRecID - 1); //序列号
BIND.head.nTotalLen = htonl(sizeof(BIND)); //总长度
BIND.head.nCommandID = htonl(SGIP_BIND); //命令ID
BIND.body.nLoginType = 1; //SP向SMG建立的连接,用于发送命令
csConfig.Lock();
strcpy(BIND.body.sLoginName, g_config.SPLoginName); //服务器端给客户端分配的登录名
csConfig.Unlock();
memset(BIND.body.sLoginName + strlen(BIND.body.sLoginName), 0, 16 - strlen(BIND.body.sLoginName));
csConfig.Lock();
strcpy(BIND.body.sLoginPass, g_config.SPLoginPwd); //服务器端和Login Name对应的密码
csConfig.Unlock();
memset(BIND.body.sLoginPass + strlen(BIND.body.sLoginPass), 0, 16 - strlen(BIND.body.sLoginPass));
memset(BIND.body.sReserve, 0, 8); //保留,扩展用
Write2RichEditAndLog("正在登录短信网关.........");
//SGIP协议连接网关
nResult = send(mtsocket, (char*)&BIND, sizeof(BIND), 0);
if (nResult == SOCKET_ERROR || nResult == 0)
{
TRACE1(_T("发送SGIP_BIND消息出错,错误代码是%d \n"), WSAGetLastError());
CString err;
err.Format("发送登录消息出错,错误代码是:%u", WSAGetLastError());
Write2RichEditAndLog(err);
csSubmitNum.Lock();
nSubmitNum = 0;
csSubmitNum.Unlock();
return FALSE;
}
while (pMTRecThread->ResumeThread()!= 0);//开始MTRec线程函数
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// MT登录移动网关 //
///////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CMPPMTConnectISMG()
{
using namespace CMPP;
csMT.Lock();
int nMTSize = MTQueue.size();
csMT.Unlock();
while (nMTSize == 0)
{
Sleep(100);
csMT.Lock();
nMTSize = MTQueue.size();
csMT.Unlock();
}
csMT.Lock();
CMessage msg = MTQueue.front();
csMT.Unlock();
///////////////////////初始化SOCKET并连接////////////////////////////////
struct sockaddr_in dest_addr; /* 目的地址*/
//创建mtsocket
mtsocket = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == mtsocket)/* 错误检查 */
{
Write2RichEditAndLog("初始化MT SOCKET失败");
return FALSE;
}
dest_addr.sin_family = AF_INET; /* host byte order */
csConfig.Lock();
dest_addr.sin_port = htons(g_config.MTPort); /* 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(mtsocket, (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 = 0; //MT连接
//计算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);
time.ReleaseBuffer();
csConfig.Unlock();
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -