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

📄 platformdlg.cpp

📁 用Visual C++开发的联通短信平台
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// 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 + -