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

📄 func.cpp

📁 本程序是实现中国移动中国联通的网关程序.代码比较完整.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "stdafx.h"
#include <windows.h>
#include <process.h>
#include <time.h>
#include <sys/timeb.h>
#include <stdio.h>
#include <winsock2.h>
#include <direct.h>
#include <stdarg.h>
#include <wchar.h>
#include <STDLIB.H>
#include "gw.h"
#include "md5.h"
#include "func.h"
#include "sock.h"

CArg arg;
DWORD WINAPI MOThread(LPVOID pp)
{
	char buffer[SMPPMAXLENGTH];
	char strSQL[512];
	fd_set rfds,afds;
	timeval tv;
	DWORD dwRet=0;
	char tmp[50];
	char msgbuffer[323];
	CMSG msg;

	tv.tv_sec=0;
	tv.tv_usec=5;
	while(arg.isActive==0)SleepEx(50,1);
	AddLog("begin to get mo.\n");
	FD_ZERO(&afds);
	FD_SET(arg.s,&afds);
	while(1)
	{
		if(arg.dwStopFlag)return 0;
		memcpy(&rfds,&afds,sizeof(afds));
		dwRet=select(FD_SETSIZE,&rfds,(fd_set*)0,(fd_set*)0,
			(struct timeval*)&tv);
		if(dwRet==SOCKET_ERROR)//network error
		{
			AddLog("select error for %d\n",GetLastError());
			SleepEx(20*1000,1);
			return ExitFromNetClose;
		}
		else if(dwRet==0)
		{
			if(arg.dwStopFlag)return 0;
			arg.dwRecv++;
			continue;//time expired
		}
		int i;
		if(i=ioctlsocket(arg.s,FIONREAD ,&dwRet))
		{
			AddLog("error for %d\n",i);
			return ExitFromNetClose;
		}else if(dwRet==0)
		{
			AddLog("socket closed by server gracefully\n");
			return ExitFromNetClose;
		}
		ZeroMemory(buffer,SMPPMAXLENGTH);
		if(i=RecvBuffer(buffer))return i;		
		arg.dwRecv++;
//now , the package should be processed.
		ZeroMemory(&msg,sizeof(CMSG));
		msg.dwCommand=(GetNByte(buffer+4,4)+0x80000000);
		msg.dwSequence=GetNByte(buffer+8,4);
		msg.dwResult=0;

		try
		{
		switch(GetNByte(buffer+4,4))
		{
		case nCMPP_CONNECT_RESP:
			if(buffer[12])
			{
				if(arg.isDebug)
					AddLog("bind to server error for: %d.\n",
					(BYTE)buffer[12]);
				arg.isActive=0;
				return ExitFromNetClose;
			}
			else
			{
				if(arg.isDebug)AddLog("bind to server ok.\n");
				arg.isActive=1;
			}
		break;
		case nCMPP_TERMINATE_RESP:
			closesocket(arg.s);
			arg.isActive=0;
			return 0;
		break;
		case nCMPP_SUBMIT_RESP:
			dwRet=(BYTE)buffer[20];
			SetWindow(-1);
			wtos(msg.szContent,GetNByte(buffer+12,4),GetNByte(buffer+12+4,4));
			if(dwRet)
			{
				sprintf(strSQL,"exec sp_send_mt_error %d,%d,%d",
					arg.iChannelNum,GetNByte(buffer+8,4),dwRet);
				if(arg.isDebug)AddLog("error: %s\n",strSQL);
				arg.pCnnGSM->Errors->Clear();
				arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);					
			}else
			{
				AddResp("Resp",0,"%d,%d,%.20s\n",
					arg.iChannelNum,GetNByte(buffer+8,4),msg.szContent);
				sprintf(strSQL,"exec sp_send_mt_resp %d,%d,'%.20s'",
					arg.iChannelNum,GetNByte(buffer+8,4),msg.szContent);
				if(arg.isDebug)AddLog("resp: %s\n",strSQL);
				arg.pCnnGSM->Errors->Clear();
				arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
			}
		break;
		case nCMPP_QUERY_RESP:
		break;
		case nCMPP_CANCEL_RESP:
		break;
		case nCMPP_ACTIVE_TEST:
			AddLog("get active test here\n");
			//set command 
			PutNByte(buffer+4,4,nCMPP_ACTIVE_TEST_RESP);
			buffer[12]=0;
			PutNByte(buffer,4,12+1);
			if(i=SendBuffer(buffer,13))
				return i;
			arg.isActive=1;
		break;
		case nCMPP_ACTIVE_TEST_RESP:
			if(arg.isDebug)AddLog("get cmpp active test resp.\n");
			arg.isActive=1;
		break;
		case nCMPP_DELIVER:
			if(buffer[75]==0)//是否是状态报告
			{//deliver process
				wtos(tmp,GetNByte(buffer+12,4),GetNByte(buffer+12+4,4));
				for(i=0;i<(BYTE)buffer[76];i++)//状态报告标志后面就是1字节的长度标志
					sprintf(msgbuffer+i*2,"%.2x",//长度标志后面就是信息体
					(BYTE)(buffer[77+i]));
				sprintf(strSQL,"exec sp_insert_mo '%s','%.21s',0x%s,%d,'%.21s',%d",
					tmp,//ismg_id
					buffer+54,//src_termid  位于msg_format之后,长度21字节
					msgbuffer,//msg
					buffer[53],//msg_format 位于第54字节
					buffer+20,//dst_termid 前面有20字节,长度为21字节
					arg.iChannelNum//channel number.
					);
				AddResp("MO",0,"%s,%.21s,0x%s,%d,%.21s,%d\n",
					tmp,//ismg_id
					buffer+54,//src_termid  位于msg_format之后,长度32字节
					msgbuffer,//msg
					buffer[53],//msg_format 位于第54字节
					buffer+20,//dst_termid 前面有20字节,长度为21字节
					arg.iChannelNum//channel number.
					);
			}
			else
			{//state report process
				//应该取之前SUBMIT是回执里的ISMGID,这时在信息体开始的8字节内
				wtos(tmp,GetNByte(buffer+77,4),GetNByte(buffer+77+4,4));
				sprintf(strSQL,"EXEC SP_STATE_REPORT %d,'%s','%.21s','%.7s','%.10s'",
					arg.iChannelNum,
					tmp,//ismg_id
					buffer+77+8+7+20,//dst_termid,在状态报告+20字节之后,长度为32字节
					buffer+77+8,//state在8字节ISMGID之后,长度7字节
					buffer+12+8+21//service id
					);
				AddResp("Status",0,"%d,%s,%.21s,%.7s,%.10s\n",
					arg.iChannelNum,
					tmp,//ismg_id
					buffer+77+8+7+20,//dst_termid,在状态报告+20字节之后,长度为32字节
					buffer+77+8,//state在8字节ISMGID之后,长度7字节
					buffer+12+8+21//service id
					);
			}
			if(arg.isDebug)AddLog("%s\n",strSQL);
			arg.pCnnGSM->Errors->Clear();
			arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
			PutNByte(buffer+4,4,0x80000000+nCMPP_DELIVER);
			buffer[20]=0;
			PutNByte(buffer,4,21);
			if(i=SendBuffer(buffer,21))return i;
		break;		
		}//end of swtich

//end of processing a package.
		}//try
		catch (_com_error &e)
		{
			AddLog("Process msg error.\n<%s>\n",strSQL);			
			AddLog("Description = '%s'\n", (char*) e.Description());
			return 0;
		}
		//end of to process the msg package.
	}//end of while 1
	return 0;
}
GW_API DWORD BeginGW(LPVOID pp)
{
	WSAData wsaData;
	DWORD dwRet;
	HANDLE h[3];
	DWORD dwRecv,dwSend;
	char szService[10];
	CMSG tm;
	int index;
	WSAStartup(0x202,&wsaData);
	tm.dwCommand=nCMPP_ACTIVE_TEST;

	if(!GetArg(&arg))
	{
		SleepEx(1000*10,1);
		return  1;
	}

	if(arg.isDebug)AddLog("GW.dll is beginning.\n\n");
	sprintf(szService,"%d",arg.SMSCPORT);
	index=0;
	while(1)
	{
		arg.s=connectTCP(arg.SMSCIP,szService);
		if(arg.s==INVALID_SOCKET)
		{			
			SleepEx(arg.iSelectInterval,1);
			index++;
			if(index<arg.nMaxReconnect)continue;
			return ExitFromNetClose;
		}
		tm.dwCommand=nCMPP_CONNECT;
		tm.dwSequence=0;
		if(dwRet=SendData(&tm,arg.pCnnGSM))
		{	
			if(dwRet==ExitFromNetClose)return ExitFromNetClose;
			tm.dwCommand=nCMPP_TERMINATE;
			dwRet=SendData(&tm,arg.pCnnGSM);
			if(dwRet==ExitFromNetClose)return ExitFromNetClose;
			tm.dwCommand=nCMPP_CONNECT;
			dwRet=SendData(&tm,arg.pCnnGSM);
			SleepEx(arg.iSelectInterval,1);
			if(dwRet)return ExitFromNetClose;				
		}else break;
	}
	try
	{
		::CoInitialize(NULL);
		TESTHR(arg.pCnnGSM.CreateInstance(__uuidof(Connection)));
		arg.pCnnGSM->ConnectionTimeout = 120;
		arg.pCnnGSM->CommandTimeout=300;
		TESTHR(arg.pCnnGSM->Open(arg.strCnn,"","",adConnectUnspecified));
		arg.pCnnGSM->Errors->Clear();
	}//try
	catch (_com_error &e)
	{
		AddLog("db connection open error.\n");			
		AddLog("Description = '%s'\n", (char*) e.Description());			
		if(arg.pCnnGSM->GetState())arg.pCnnGSM->Close();
		::CoUninitialize();
		SleepEx(arg.iSelectInterval,1);
		return 0;
	}
	dwRet=0;
	ResetEvent(arg.hGW);
	h[0]=(HANDLE)_beginthreadex(NULL,0,(unsigned int(__stdcall*)(void*))MTThread,0,0,0);
	h[1]=(HANDLE)_beginthreadex(NULL,0,(unsigned int(__stdcall*)(void*))MOThread,0,0,0);
	h[2]=arg.hGW;
	dwRecv=dwSend=0;
	tm.dwCommand=nCMPP_ACTIVE_TEST;
	while(1)
	{
		dwRet=WaitForMultipleObjects(3,h,FALSE,20*1000);
		switch(dwRet)
		{
			case WAIT_FAILED:	//error:
				AddLog("WSAWaitFor Error\n");
				ExitProcess(-1);
				break;
			case WAIT_TIMEOUT:
#if 1
				if(SendOnlyData(&tm))
				{
					TerminateThread(h[0],0);
					TerminateThread(h[1],0);
					goto RET_002;
				}
#endif
				if(arg.isMO==1) 
				{
					if(dwRecv/3>arg.dwRecv+1)
					{
						AddLog("mo no data, thread will rerun.\n");
						dwRecv=arg.dwRecv;
						dwSend=arg.dwSend;
						TerminateThread(h[0],0);
						TerminateThread(h[1],0);
						goto RET_002;
					}
				}
				else if((dwRecv/3>arg.dwRecv+1)||dwSend>arg.dwSend+50)
				{
					if(arg.isDebug>1)
						AddLog("No data, thread will rerun.\n");
						dwRecv=arg.dwRecv;
						dwSend=arg.dwSend;
						//TerminateThread(h[0],0);
						//TerminateThread(h[1],0);
						goto RET_002;
				}
				dwRecv++;dwSend++;
				if(dwRecv<arg.dwRecv)dwRecv=arg.dwRecv;
				if(dwSend<arg.dwSend)dwSend=arg.dwSend;
				break;
			case WAIT_OBJECT_0:	//mt_thread exit here
				GetExitCodeThread(h[0],&dwRet);
				if(arg.isDebug)AddLog("MTThread exit for %d.\n",dwRet);
				if(dwRet==ExitFromNetClose||dwRet==0)
				{
					//TerminateThread(h[1],0);
					goto RET_002;
				}
				CloseHandle(h[0]);
				h[0]=(HANDLE)_beginthreadex(NULL,0,
					(unsigned int(__stdcall*)(void*))MTThread,0,0,0);
				if(h[0]==NULL)
				{
					//TerminateThread(h[1],0);
					goto RET_002;
				}
				break;
			case WAIT_OBJECT_0 +1://mo thread exit here.
				GetExitCodeThread(h[1],&dwRet);
				if(arg.isDebug)AddLog("MOThread exit for %d.\n",dwRet);
				if(dwRet==ExitFromNetClose||dwRet==0)
				{
					TerminateThread(h[0],0);
					return 0;
					goto RET_002;
				}
				CloseHandle(h[1]);
				h[1]=(HANDLE)_beginthreadex(NULL,0,
					(unsigned int(__stdcall*)(void*))MOThread,
					0,0,0);
				if(h[1]==NULL)
				{
					//TerminateThread(h[0],0);
					goto RET_002;
				}
				break;
			case WAIT_OBJECT_0+2:	//EventForExit
				AddLog("Get msg to stop GW.\n");
				//TerminateThread(h[0],0);
				//TerminateThread(h[1],0);
				goto RET_002;
				break;
		}//switch(dwRet)
	}//end fo while (1)
RET_002:
	AddLog("clean up\n");
	arg.dwStopFlag=0x7e;
	SleepEx(1000,1);
	WSACleanup();
	if(arg.pCnnGSM->GetState())arg.pCnnGSM->Close();
#if ONESECTION1
	DeleteCriticalSection(&(arg.syc1));
#endif
#if ONESECTION2
	DeleteCriticalSection(&(arg.syc2));
#endif
#if ONESECTION3
	DeleteCriticalSection(&(arg.syc3));
#endif	
	::CoUninitialize();
	AddLog("exit BeginGW\n");
	return 0;
}
void PutByteString(char* dest,
				   char* source,
				   int length)
{
	int i=0;
	if(source==NULL)return;
	for(i=0;i<length;i++)
		dest[i]=source[i];
}
void PutNByte(char* buffer,BYTE b,DWORD in)
{
        int i; 
		if(b>4)b=4;
        for(i=0;i<b;i++) 
        { 
            *(buffer+b-1-i)=char(in&0xFF);
			in>>=8;
        } 
}
DWORD GetTime()
{
	int ret=0;
	time_t tt;
	struct tm *now;
	char buf[20];

	time( &tt);
	now = localtime( &tt);
	sprintf( buf, "%02d%02d%02d%02d%02d",
		now->tm_mon + 1,
		now->tm_mday,
		now->tm_hour,
		now->tm_min,
		now->tm_sec);
	ret=atoi(buf);
	return ret;
}
DWORD GetTimeMillSec()
{
	int ret=0;
	struct _timeb timebuffer;
	_ftime(&timebuffer);
	ret=timebuffer.millitm+timebuffer.time%3600*1000;
	return ret;
}

void GetTime(char* buffer,int period)
{
	char date[20],time[20];
	int d,h,m;
	int year,month;
	_strdate(date);
	_strtime(time);
	m=atoi(time+3)+period;
	h=m/60+atoi(time);m%=60;
	d=h/24+atoi(date+3);h%=24;
	month=atoi(date);
	year=atoi(date+6);
	switch(month){
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		if(d>31){month+=d/31;d%=31;}
		break;
	case 4:
	case 6:
	case 9:
	case 11:
		if(d>30){month+=d/30;d%=30;}
		break;
	case 2:
		if((year%4==0&&year%100>0)||year%400==0){
			if(d>29){month+=d/29;d%=29;}
		}else 
		{
			if(d>28){month+=d/28;d%=28;}
		}
	}
	if(month>12){year+=month/12;month%=12;}
	sprintf(buffer,"%.2d%.2d%.2d%.2d%.2d%.2d",
		year,month,d,h,m,atoi(time+6));
	strcpy(buffer+12,"032+");
}

⌨️ 快捷键说明

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