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

📄 deliverthread.cpp

📁 一个用vc开发的Sgip通讯程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// DeliverThread.cpp : implementation file
//

#include "stdafx.h"
#include <process.h>
#include "SGip.h"
#include "DeliverThread.h"
#include "sqlExec.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDeliverThread
BOOL g_bDeliverThreadExit=false;
extern char SGIP_INI_FILE[100];           //配置信息
extern bool ACTIVE_FLAG;

IMPLEMENT_DYNCREATE(CDeliverThread, CWinThread)

void WriteDeliverActiveFlag(const char* szActiveFileName)
{
	static			tOldTime=time(NULL);
	time_t			tCurTime;
	double			lDiffTime;

	time(&tCurTime);
	lDiffTime = abs(difftime(tCurTime , tOldTime)) - 30;
	if (lDiffTime > 0 ) 
	{
		TRY
		{
		   CFile f( szActiveFileName, CFile::modeCreate | CFile::modeWrite );
		   f.Close();
		}
		CATCH( CFileException, e )
		{
			CString strMsg;
			strMsg.Format("文件%s不能被创建.",szActiveFileName);
			LogFile(strMsg);
		}
		END_CATCH
		tOldTime = tCurTime;
	}
}

CDeliverThread::CDeliverThread()
{
	m_bAutoDelete = false;
	m_astCmdTab = NULL;
	m_pSection=NULL;
	srand(time(NULL));

    m_bConnectDeliverDB = FALSE;
	//add by ycf20020825
	m_psValidMb      = NULL ;//有效号码段,号码段位数为11
    m_psInvalidMb    = NULL ;//无效号码段,号码段位数为11
    m_psInvdScrapMb  = NULL ;//有效离散零星号码段,号码段位数为11
    m_psValidScrapMb = NULL ;//无效离散零星号码段,号码段位数为11
    m_sGameQuit      = NULL ;
}

CDeliverThread::~CDeliverThread()
{
	if( m_astCmdTab)
	{
		delete [] m_astCmdTab ;
		m_astCmdTab = NULL;
	}
	
	if(m_pSection != NULL)	
	{
		delete[] m_pSection;
		m_pSection = NULL;
	}

	// add by ycf 20020825
	m_saValidMbHead.RemoveAll() ;
    m_saInvdMbHead.RemoveAll() ;
    if(m_psValidMb != NULL )
	{//有效号码段,号码段位数为11
        delete [] m_psValidMb ;
        m_psValidMb = NULL;
	}
    if(m_psInvalidMb != NULL )
	{///无效号码段,号码段位数为11
        delete [] m_psInvalidMb ;
        m_psInvalidMb = NULL;
	}
    if(m_psValidScrapMb != NULL )
	{///无效离散零星号码段,号码段位数为11
        delete [] m_psInvdScrapMb ;
        m_psValidScrapMb = NULL;
	}
    if(m_psInvdScrapMb != NULL )
	{///无效离散零星号码段,号码段位数为11
        delete [] m_psInvdScrapMb ;
        m_psInvdScrapMb = NULL;
	} 
	if (m_sGameQuit != NULL)
	{
		delete [] m_sGameQuit;
		m_sGameQuit = NULL;
	}
}

void CDeliverThread::LoadIni()
{
	CString  strField;
	SDeliverNodeBuffer *pstNodeBuf;
	int nTotalDeliverServer;
	char szServiceType[20];

	m_nMoniterPort = GetPrivateProfileInt("系统","MO监控端口",6998,SGIP_INI_FILE);
	GetPrivateProfileString("系统","系统用户名","land",m_szUserName,6,SGIP_INI_FILE);
	GetPrivateProfileString("系统","系统密码","land",m_szPassword,10,SGIP_INI_FILE);
	GetPrivateProfileString("系统","数据源","DSN=sm;UID=sa;PWD=",m_szDSN,100,SGIP_INI_FILE);
	m_nMaxIdleTimes = GetPrivateProfileInt("系统","MO最大空闲时间",360,SGIP_INI_FILE);
	GetPrivateProfileString("系统","MO指令错误日志表","gr_deliver_error",m_szErrorTable,50,SGIP_INI_FILE);
	GetPrivateProfileString("系统","指令错误帮助信息","",m_szHelp,140,SGIP_INI_FILE);

	GetPrivateProfileString("系统","MO接收日志表名","gr_deliver_log",m_szDeliverLogTableName,100,SGIP_INI_FILE);
	GetPrivateProfileString("系统","MT发送表名","gr_sendmessage",m_szTableName,50,SGIP_INI_FILE);

	m_bDeliverToEveryDayTable=GetPrivateProfileInt("系统","MO是否每天一个日志表记录",0,SGIP_INI_FILE);

	m_deffee.iFeeType=GetPrivateProfileInt("系统","错误指令计费类别",2,SGIP_INI_FILE);
	m_deffee.iMotomtFlag=GetPrivateProfileInt("系统","错误指令MOTOMTFLAG",0,SGIP_INI_FILE);
	m_deffee.iFeeValue=GetPrivateProfileInt("系统","错误指令信息费",10,SGIP_INI_FILE);
	m_deffee.iGivenValue=GetPrivateProfileInt("系统","错误指令赠话费",0,SGIP_INI_FILE);
	GetPrivateProfileString("系统","错误指令业务代码","SHZX",szServiceType,20,SGIP_INI_FILE);
	m_deffee.strServiceType.Format("%s",szServiceType);


	nTotalDeliverServer =  GetPrivateProfileInt("系统","MO短信服务器开启个数",1,SGIP_INI_FILE);
	m_pSection=new CCriticalSection[nTotalDeliverServer];
	for(int i=0;i<nTotalDeliverServer;i++)
	{
		pstNodeBuf = new SDeliverNodeBuffer;
		strField.Format("MO短信服务器%d",i+1);
		pstNodeBuf->m_nLocalPort = GetPrivateProfileInt(strField,"本地端口",8801,SGIP_INI_FILE);
		GetPrivateProfileString(strField,"用户名","CJXH",pstNodeBuf->m_szUser,20,SGIP_INI_FILE);
		GetPrivateProfileString(strField,"密码","",pstNodeBuf->m_szPassword,20,SGIP_INI_FILE);
		GetPrivateProfileString(strField,"缺省主叫号码","",pstNodeBuf->m_szSourceNumber,20,SGIP_INI_FILE);
		GetPrivateProfileString(strField,"本地地址","",pstNodeBuf->m_szLocalIP,20,SGIP_INI_FILE);
		pstNodeBuf->nID=i;
		m_stDeliverNodeBuf.Add(pstNodeBuf);
	}

	//  add by ycf 20020825
	m_bEnableNumCtrl = GetPrivateProfileInt("系统","号码段控制功能开关",0,SGIP_INI_FILE);
    m_bMbCtrlFlag    = GetPrivateProfileInt("系统","号码段位数状态",0,SGIP_INI_FILE);
    GetPrivateProfileString("系统","非本地用户反馈信息","对不起,您是非本地区用户,暂时不能参加我们的短信游戏。",m_szErrMobileMsg,140,SGIP_INI_FILE);
    
	GetPrivateProfileString("系统","SP接入号码","8788",m_szSPNumber,21,SGIP_INI_FILE);
	m_bReport     = GetPrivateProfileInt("系统","开启错误状态报告",0,SGIP_INI_FILE);

	m_bEnableGameQuit = GetPrivateProfileInt("系统","开启取消指令功能",0,SGIP_INI_FILE);
	GetPrivateProfileString("系统","取消指令","999",m_szCancel,10,SGIP_INI_FILE);
	GetPrivateProfileString("系统","取消等同指令","QX",m_szEqual,10,SGIP_INI_FILE);

	GetPrivateProfileString("系统","取消指令帮助信息1","",m_szCancelHelp1,140,SGIP_INI_FILE);
	GetPrivateProfileString("系统","取消指令帮助信息2","",m_szCancelHelp2,140,SGIP_INI_FILE);

	GetPrivateProfileString("系统","取消所有指令","9999",m_szCancelAll,10,SGIP_INI_FILE);
	GetPrivateProfileString("系统","取消所有等同指令","00000",m_szEqualAll,10,SGIP_INI_FILE);

	GetPrivateProfileString("系统","取消所有业务帮助信息","",m_szCancelAllHelp,140,SGIP_INI_FILE);
    
	m_canclefee.iFeeType=GetPrivateProfileInt("系统","取消指令计费类别",2,SGIP_INI_FILE);
	m_canclefee.iMotomtFlag=GetPrivateProfileInt("系统","取消指令MOTOMTFLAG",0,SGIP_INI_FILE);
	m_canclefee.iFeeValue=GetPrivateProfileInt("系统","取消指令信息费",10,SGIP_INI_FILE);
	m_canclefee.iGivenValue=GetPrivateProfileInt("系统","取消指令赠话费",0,SGIP_INI_FILE);
	GetPrivateProfileString("系统","取消指令业务代码","SHZX",szServiceType,20,SGIP_INI_FILE);
	m_canclefee.strServiceType.Format("%s",szServiceType);

	m_bMonth = GetPrivateProfileInt("系统","开启包月功能",0,SGIP_INI_FILE);
    GetPrivateProfileString("系统","包月接收表","sm_Game_Deliver",m_szMonthTable,50,SGIP_INI_FILE);

	m_bChat     = GetPrivateProfileInt("系统","开启聊天功能",0,SGIP_INI_FILE);
    m_nChatLen  = GetPrivateProfileInt("系统","会员号长度",4,SGIP_INI_FILE);
    GetPrivateProfileString("系统","聊天接收表","gr_deliver_matrix",m_szChatTable,50,SGIP_INI_FILE);

    m_bForbid         = GetPrivateProfileInt("系统","开启搜索禁止用户",0,SGIP_INI_FILE);
	m_bForbidFlag     = GetPrivateProfileInt("系统","搜索禁止用户标志",0,SGIP_INI_FILE);
    GetPrivateProfileString("系统","搜索禁止用户时间","2230",m_szForbidTime,5,SGIP_INI_FILE);
	GetPrivateProfileString("系统","当前日期","2002-11-27",m_szCurrentDate,11,SGIP_INI_FILE);

	m_bRecieve         = GetPrivateProfileInt("系统","允许接收其它格式短信",0,SGIP_INI_FILE);

}

BOOL CDeliverThread::ConnectDB()
{
	try
	{
		m_database.OpenEx(m_szDSN,CDatabase::noOdbcDialog);
	}
    catch( CDBException* e )
	{
		LogMsg(e->m_strError);
		LogMsg("连接MO数据库失败!");
		m_bConnectDeliverDB = FALSE;
		return FALSE;
	}

    m_bConnectDeliverDB = TRUE;
	LogMsg("连接MO数据库成功!");
	
	return TRUE;
}

void CDeliverThread::LogMsg(const char* szMsg,int iFlag)
{
	CTcpAsyncSocket *pstMoniterSocket;
	CString strMsg;
	CTime stTime = CTime::GetCurrentTime();

	printf("[%d-%d %02d:%02d:%02d]%s\r\n",stTime.GetMonth(),stTime.GetDay(),stTime.GetHour(),stTime.GetMinute(),stTime.GetSecond(),szMsg);
	strMsg.Format("[%d-%d %02d:%02d:%02d]%s\r\n",stTime.GetMonth(),stTime.GetDay(),stTime.GetHour(),stTime.GetMinute(),stTime.GetSecond(),szMsg);
	if(iFlag)
		return;
	for(int i=0;i<m_stMoniterNodeBuf.GetSize();i++)
	{
		pstMoniterSocket =(CTcpAsyncSocket *)m_stMoniterNodeBuf.GetAt(i);
		if(SendPacket(pstMoniterSocket,(unsigned char*)strMsg.LockBuffer(),strMsg.GetLength()) == -1)
		{	//new added by ps 2001.8.27 for clean unused socket
			pstMoniterSocket->Close();
			delete m_stMoniterNodeBuf.GetAt(i);
			m_stMoniterNodeBuf.RemoveAt(i);
		}
		strMsg.UnlockBuffer();
	}
}

void AcceptProc(void* pParam)
{
	SDeliverNodeBuffer* pstNode=(SDeliverNodeBuffer*)pParam;
	SOCKADDR saClient;
	CTcpAsyncSocket* pstAcceptSocket;

	try 
	{
		pstAcceptSocket = new CTcpAsyncSocket();
		if(!pstNode->m_stListenSocket.Accept(*pstAcceptSocket,&saClient))
		{
			delete pstAcceptSocket;
			_endthread();
		}
		pstNode->pstThread->m_pSection[pstNode->nID].Lock(INFINITE);
		pstNode->pstThread->AddToList(pstNode,pstAcceptSocket);
		pstNode->pstThread->m_pSection[pstNode->nID].Unlock();
		_beginthread(AcceptProc,0,pParam);		//get ready for another connection
	}
	catch(const char* e)
	{
		printf("%s\n",e);
		delete pstAcceptSocket;
	}
	_endthread();
}

void AcceptMoniterDeliverProc(void* pParam)
{
	CDeliverThread* pstThread=(CDeliverThread*)pParam;
	SOCKADDR saClient;
	CTcpAsyncSocket* pstAcceptSocket;

	try 
	{
		pstAcceptSocket = new CTcpAsyncSocket();
		if(!pstThread->m_stMoniterSocket.Accept(*pstAcceptSocket,&saClient))
		{
			delete pstAcceptSocket;
			_endthread();
		}
		pstThread->AddToMoniterList(pstAcceptSocket);
		_beginthread(AcceptMoniterDeliverProc,0,pParam);		//get ready for another connection
	}
	catch(const char* e)
	{
		printf("%s\n",e);
		delete pstAcceptSocket;
	}
	_endthread();
}

void RunDeliverProc(void* pParam)
{
	CDeliverThread* pstThread=(CDeliverThread*)pParam;

	pstThread->Run();
	_endthread();
}

BOOL CDeliverThread::InitSocket()
{
	SDeliverNodeBuffer *pstNode;

	m_stMoniterSocket.Close();
	m_stMoniterSocket.Create(m_nMoniterPort);
	m_stMoniterSocket.SetNonBlockingMode(false);
	m_stMoniterSocket.Listen();
	_beginthread(AcceptMoniterDeliverProc,0,this);

	//start connect to SMG
	for(int i=0;i<m_stDeliverNodeBuf.GetSize();i++)
	{
		pstNode =(SDeliverNodeBuffer *)m_stDeliverNodeBuf.GetAt(i);
		pstNode->m_stListenSocket.Close();
		//绑定本地IP
		if(strlen(pstNode->m_szLocalIP))
		{
			pstNode->m_stListenSocket.Create(pstNode->m_nLocalPort,SOCK_STREAM,pstNode->m_szLocalIP);
		}
		else
		{
			pstNode->m_stListenSocket.Create(pstNode->m_nLocalPort);
		}
		pstNode->m_stListenSocket.SetNonBlockingMode(false);
		pstNode->m_stListenSocket.Listen();
		pstNode->pstThread = this;
		_beginthread(AcceptProc,0,pstNode);
	}

	return TRUE;
}

void CDeliverThread::AddToList(SDeliverNodeBuffer *pstDeliverNodeBuf,CTcpAsyncSocket* pstClientSocket)
{
	SClientNodeBuffer *pstNodeBuf;

	pstNodeBuf = new SClientNodeBuffer;
	pstNodeBuf->m_pstClientSocket =pstClientSocket;
	pstNodeBuf->m_iSequenceId =1;
	pstNodeBuf->m_bConnected = false;
	time(&pstNodeBuf->m_tActiveTime);
	pstDeliverNodeBuf->m_stClientNodeBuf.Add(pstNodeBuf);
}

void CDeliverThread::AddToMoniterList(CTcpAsyncSocket* pstClientSocket)
{
	m_stMoniterNodeBuf.Add(pstClientSocket);
}

int CDeliverThread::SendSGipUnBind(SClientNodeBuffer *pstNodeBuf)
{
	CSGipPdu stPdu;

	stPdu.UnBind();
	return SendPacket(pstNodeBuf->m_pstClientSocket,stPdu.GetBuffer(),stPdu.GetLen());
}

int CDeliverThread::SendSGipBindResp(SClientNodeBuffer *pstNodeBuf,const char* szRecvBuf,char cResult)
{
	CSGipPdu stPdu;

	stPdu.BindResp(szRecvBuf,cResult);
	return SendPacket(pstNodeBuf->m_pstClientSocket,stPdu.GetBuffer(),stPdu.GetLen());
}

int CDeliverThread::SendSGipUnBindResp(SClientNodeBuffer *pstNodeBuf,const char* szRecvBuf)
{
	CSGipPdu stPdu;

	stPdu.UnBindResp(szRecvBuf);
	return SendPacket(pstNodeBuf->m_pstClientSocket,stPdu.GetBuffer(),stPdu.GetLen());
}

int CDeliverThread::SendSGipDeliverResp(SClientNodeBuffer *pstNodeBuf,const char* szRecvBuf,char cResult)
{
	CSGipPdu stPdu;

	stPdu.DeliverResp(szRecvBuf,cResult);
	return SendPacket(pstNodeBuf->m_pstClientSocket,stPdu.GetBuffer(),stPdu.GetLen());
}

int CDeliverThread::SendSGipReportResp(SClientNodeBuffer *pstNodeBuf,const char* szRecvBuf,char cResult)
{
	CSGipPdu stPdu;

	stPdu.ReportResp(szRecvBuf,cResult);
	return SendPacket(pstNodeBuf->m_pstClientSocket,stPdu.GetBuffer(),stPdu.GetLen());
}

void CDeliverThread::HandleActiveTest()
{
	time_t			tCurTime;
	double			lDiffTime;
	SDeliverNodeBuffer *pstDeliverNodeBuf;
	SClientNodeBuffer *pstClientNodeBuf;
	int i,k;
	int iInvalidClient;

	time(&tCurTime);

	for(i=0;i<m_stDeliverNodeBuf.GetSize();i++)
	{
		m_pSection[i].Lock(-1);
		pstDeliverNodeBuf =(SDeliverNodeBuffer *)m_stDeliverNodeBuf.GetAt(i);
		iInvalidClient=0;
		while(iInvalidClient>-1)
		{
			iInvalidClient=-1;
			for(k=0;k<pstDeliverNodeBuf->m_stClientNodeBuf.GetSize();k++)
			{
				pstClientNodeBuf =(SClientNodeBuffer *)pstDeliverNodeBuf->m_stClientNodeBuf.GetAt(k);
				//检查是否IDLE已经超过规定时间
				lDiffTime = abs(difftime(tCurTime,pstClientNodeBuf->m_tActiveTime)) - m_nMaxIdleTimes;
				if(lDiffTime >0 || pstClientNodeBuf->m_pstClientSocket->m_hSocket==INVALID_SOCKET)
				{
					time(&pstClientNodeBuf->m_tActiveTime);
					LogMsg("清理空闲端口.");
					iInvalidClient=k;
					break;
				}
			}
			if(iInvalidClient>-1)
 			{
				pstClientNodeBuf->m_pstClientSocket->Close();
				delete pstClientNodeBuf->m_pstClientSocket;
				delete pstDeliverNodeBuf->m_stClientNodeBuf.GetAt(k);
				pstDeliverNodeBuf->m_stClientNodeBuf.RemoveAt(k);
			}
		}
		m_pSection[i].Unlock();
	}
}

void CDeliverThread::HandleDeliverMsg(SDeliverNodeBuffer *pstDeliverNode,SClientNodeBuffer *pstNodeBuf,char *szRecvBuf,int nLen)
{
	CSGipPdu stPdu;
	int nCommandID,nSequence1,nSequence2,nSequence3;
	char cResult;
	SSGipBind* pstBind;

	time(&pstNodeBuf->m_tActiveTime);
	stPdu.GetHeaderInfo(szRecvBuf,nCommandID,nSequence1,nSequence2,nSequence3);
	switch(nCommandID)
	{
	case SGIP_BIND: //bind rep
		pstBind =(SSGipBind*)(szRecvBuf + PDU_HEADER_SIZE);
		if(pstBind->cLoginType == 2)
		{
			pstNodeBuf->m_bConnected = true;
			LogMsg("SMG向SP Bind成功!");
			cResult = 0;
		}
		else
		{
			LogMsg("Bind失败--Bind类型错误!!");
			pstNodeBuf->m_bConnected = false;
			cResult = 1;
		}
		cResult =0;
		SendSGipBindResp(pstNodeBuf,szRecvBuf,cResult);
		break;

	case SGIP_UNBIND:
		SendSGipUnBindResp(pstNodeBuf,szRecvBuf);
		LogMsg("对方MO端UNBIND包.");
		pstNodeBuf->m_pstClientSocket->m_hSocket=INVALID_SOCKET;
		break;

	case SGIP_DELIVER:
		HandleDeliverPdu(pstNodeBuf,szRecvBuf);
		break;
	case SGIP_REPORT:
		HandleReportPdu(pstNodeBuf,szRecvBuf);
		break;
	default:
		LogMsg("未知包。");
		break;
	}
}

BOOL CDeliverThread::HandleReportPdu(SClientNodeBuffer *pstNodeBuf,const char* szRecvBuf)
{
	CString		strSql,strTmp;
	CSqlExec	sql_db(&m_database);
	SSGipReport *pstReport;
	CString		strMsg;
	CString		strMsgID;
	int  nRecCount = -1,nInValid = 0;
 
	SendSGipReportResp(pstNodeBuf,szRecvBuf,SGIP_OK);
	pstReport =(SSGipReport*)(szRecvBuf + PDU_HEADER_SIZE);
	strMsg.Format("[MO]收到状态报告信息,类型:%d,用户号:%s,state:%d,errorcode:%d.",
		pstReport->cReportType,pstReport->szUserNumber,pstReport->cState,pstReport->cErrorCode);
	LogMsg(strMsg);
	
	strMsgID.Format("%d%d%d",ntohl(pstReport->nSubmitSequenceNumber1),ntohl(pstReport->nSubmitSequenceNumber2),ntohl(pstReport->nSubmitSequenceNumber3));

⌨️ 快捷键说明

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