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

📄 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];

	tv.tv_sec=0;
	tv.tv_usec=5;
	while(arg.isActive==0)SleepEx(500,1);
	if(arg.isDebug)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);
		arg.dwRecv++;
		if(dwRet==SOCKET_ERROR)//network error
		{
			AddLog("select error for %d\n",GetLastError());
			SleepEx(20*1000,1);
			return ExitFromNetClose;
		}
		else if(dwRet==0)
		{
			continue;//time expired
		}
		int i;

		ZeroMemory(buffer,SMPPMAXLENGTH);
		if(i=RecvBuffer(buffer))
		{
			return i;
		}

		try
		{
		switch(GetNByte(buffer+4,4))
		{
		case nCMPP_CONNECT_RESP:
			if(GetNByte(buffer+12,4))
			{
				AddLog("bind to server error for: %d.\n",GetNByte(buffer+12,4));
				arg.isActive=0;
				return ExitFromNetClose;
			}
			else
			{
				AddLog("bind to chen2 server ok.\n");
				arg.isActive=1;
			}
		break;
		case nCMPP_TERMINATE_RESP:
			closesocket(arg.s);
			arg.isActive=0;
			return 0;
		break;
		case nCMPP_SUBMIT_RESP:
			SetWindow(-1);
			dwRet=GetNByte(buffer+20,4);
			wtos(msgbuffer,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
			{
				sprintf(strSQL,"exec sp_send_mt_resp %d,%d,'%.20s'",
					arg.iChannelNum,GetNByte(buffer+8,4),msgbuffer);
				if(arg.isDebug>1)AddLog("resp: %s\n",strSQL);
				AddResp("Resp",0,"%d,%d,%.20s\n",
					arg.iChannelNum,GetNByte(buffer+8,4),msgbuffer);
				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))return i;
			arg.isActive=1;
		break;
		case nCMPP_ACTIVE_TEST_RESP:
			if(arg.isDebug)AddLog("cmpp active test ok.\n");
			arg.isActive=1;
		break;
		case nCMPP_DELIVER:
			if(buffer[87]==0)//是否是状态报告
			{//deliver process
				wtos(tmp,GetNByte(buffer+12,4),GetNByte(buffer+12+4,4));
				for(i=0;i<(BYTE)buffer[88];i++)//状态报告标志后面就是1字节的长度标志
					sprintf(msgbuffer+i*2,"%.2x",//长度标志后面就是信息体
					(BYTE)(buffer[89+i]));
				//if(strlen(buffer+41)>1)
				//{
						sprintf(strSQL,"exec sp_insert_mo '%s','%.32s',0x%s,%d,'%.21s',%d,'%.20s','%.10s'",
							tmp,//ismg_id
							buffer+54,//src_termid  位于msg_format之后,长度32字节
							msgbuffer,//msg
							(BYTE)buffer[53],//msg_format 位于第54字节
							buffer+20,//dst_termid 前面有20字节,长度为21字节
							arg.iChannelNum,//channel number.
							buffer+GetNByte(buffer,4)-20,//LinkID是最后20字节
							buffer+41//spserviceid前面有41字节
							);

						AddResp("MO",0,"%d,%s,%.32s,0x%s,%d,%.21s,%.20s,%.10s\n",
							arg.iChannelNum,//channel number.
							tmp,//ismg_id
							buffer+54,//src_termid  位于msg_format之后,长度32字节
							msgbuffer,//msg
							(BYTE)buffer[53],//msg_format 位于第54字节
							buffer+20,//dst_termid 前面有20字节,长度为21字节
							buffer+GetNByte(buffer,4)-20,//LinkID是最后20字节
							buffer+41//spserviceid前面有41字节
							);
					/*}else
					{
						sprintf(strSQL,"exec sp_insert_mo '%s','%.32s',0x%s,%d,'%.21s',%d",
							tmp,//ismg_id
							buffer+54,//src_termid  位于msg_format之后,长度32字节
							msgbuffer,//msg
							(BYTE)buffer[53],//msg_format 位于第54字节
							buffer+20,//dst_termid 前面有20字节,长度为21字节
							arg.iChannelNum//channel number.
							);

						AddResp("MO",0,"%d,%s,%.32s,0x%s,%d,%.21s\n",
							arg.iChannelNum,//channel number.
							tmp,//ismg_id
							buffer+54,//src_termid  位于msg_format之后,长度32字节
							msgbuffer,//msg
							(BYTE)buffer[53],//msg_format 位于第54字节
							buffer+20//dst_termid 前面有20字节,长度为21字节
							);
					}*/
			}
			else
			{//state report process
				//应该取之前SUBMIT是回执里的ISMGID,这时在信息体开始的8字节内
				wtos(tmp,GetNByte(buffer+89,4),GetNByte(buffer+89+4,4));
				sprintf(strSQL,"EXEC SP_STATE_REPORT %d,'%s','%.32s','%.7s','%.10s'",
					arg.iChannelNum,
					tmp,//ismg_id
					buffer+89+8+7+20,//dst_termid,在状态报告+20字节之后,长度为32字节
					buffer+89+8,//state在8字节ISMGID之后,长度7字节
					buffer+12+8+21
					);
				AddResp("Status",0,"%d,%s,%.32s,%.7s,%.10s\n",
					arg.iChannelNum,
					tmp,//ismg_id
					buffer+89+8+7+20,//dst_termid,在状态报告+20字节之后,长度为32字节
					buffer+89+8,//state在8字节ISMGID之后,长度7字节
					buffer+12+8+21);
			}
			if(arg.isDebug>1)AddLog("%s\n",strSQL);
			arg.pCnnGSM->Errors->Clear();
			arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
			PutNByte(buffer+20,4,0);
			PutNByte(buffer,4,24);
			PutNByte(buffer+4,4,nCMPP_DELIVER_RESP);
			if(i=SendBuffer(buffer))
			{
				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.
	}
	return 0;
}
GW_API DWORD BeginGW(LPVOID pp)
{
	WSAData wsaData;
	DWORD dwRet;
	HANDLE h[3];
	DWORD dwRecv,dwSend;
	CMSG tm;
	int index=0;
	char szService[10];
	
	AddLog("GW.dll is beginning.\n\n");
	WSAStartup(0x202,&wsaData);

	if(!GetArg(&arg))
	{
		SleepEx(1000*10,1);
		AddLog("read arg file failed\n");
		return  1;
	}

	AddLog("GW.dll is beginning.\n\n");
	ZeroMemory(&tm,sizeof(CMSG));
	sprintf(szService,"%d",arg.SMSCPORT);
	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)
			{
	AddLog("xing1\n");	
				return 0;
			}
			tm.dwCommand=nCMPP_TERMINATE;
			dwRet=SendData(&tm,arg.pCnnGSM);
			if(dwRet==ExitFromNetClose)
			{
	AddLog("xing2\n");	
				return 0;
			}
			tm.dwCommand=nCMPP_CONNECT;
			dwRet=SendData(&tm,arg.pCnnGSM);
			SleepEx(arg.iSelectInterval,1);
			if(dwRet)
			{
		AddLog("xing3\n");	
				return 0;				
			}
		}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();
		return false;
	}


	dwRet=0; 
	ResetEvent(arg.hGW);
	h[0]=arg.hGW;
	h[1]=(HANDLE)_beginthreadex(NULL,0,(unsigned int(__stdcall*)(void*))MOThread,0,0,0);
	if(arg.isMO==0 || arg.isMO==3)
	h[2]=(HANDLE)_beginthreadex(NULL,0,(unsigned int(__stdcall*)(void*))MTThread,0,0,0);
	dwRecv=dwSend=0;
	tm.dwCommand=nCMPP_ACTIVE_TEST;
	while(1)
	{
		if(arg.isMO==0 || arg.isMO==3)
		dwRet=WaitForMultipleObjects(3,h,FALSE,arg.bWaitTime*1000);
		else
		dwRet=WaitForMultipleObjects(2,h,FALSE,arg.bWaitTime*1000);
		switch(dwRet)
		{
			case WAIT_FAILED:	//error:
				AddLog("WSAWaitFor Error\n");				
				ExitProcess(0);
				break;
			case WAIT_TIMEOUT:
#if 1
				if(SendOnlyData(&tm))
				{
					arg.dwStopFlag=0x7e;
					SleepEx(1000,1);
					goto RETURN_001;
				}
#endif
				if(arg.isMO)
				{
					if(dwRecv>(arg.dwRecv+5))
						AddLog("Mo thread in problem, process will rerun.\n");
				}
				else if(dwRecv>(arg.dwRecv+5)||dwSend>arg.dwSend+50)
				{
					AddLog("Mt thread in problem, process will rerun.\n");
					dwRecv=arg.dwRecv;
					dwSend=arg.dwSend;
					//StopGW();
					//TerminateThread(h[2],0);
					//TerminateThread(h[1],0);
					goto RETURN_001;
				}
				dwRecv++;dwSend++;
				if(dwRecv<arg.dwRecv)dwRecv=arg.dwRecv;
				if(dwSend<arg.dwSend)dwSend=arg.dwSend;
				break;
			case WAIT_OBJECT_0+2:	//mt_thread exit here
				GetExitCodeThread(h[2],&dwRet);
				if(arg.isDebug)AddLog("MTThread exit for %d.\n",dwRet);
				if(dwRet==ExitFromNetClose||dwRet==0)
				{
					arg.dwStopFlag=0x7e;
					arg.s=0;
					//TerminateThread(h[1],0);
					//StopGW();
					goto RETURN_001;
				}
				CloseHandle(h[0]);
				h[2]=(HANDLE)_beginthreadex(NULL,0,
					(unsigned int(__stdcall*)(void*))MTThread,0,0,0);
				if(h[2]==NULL)
				{
					//TerminateThread(h[1],0);
					//StopGW();
					arg.dwStopFlag=0x7e;
					goto RETURN_001;
				}
				break;
			case WAIT_OBJECT_0 +1://mo thread exit here.
				GetExitCodeThread(h[1],&dwRet);
				AddLog("MOThread exit for %d.\n",dwRet);
				if(dwRet==ExitFromNetClose||dwRet==0)
				{
					arg.dwStopFlag=0x7e;
					arg.s=0;
					//if(arg.isMO==0)TerminateThread(h[2],0);
					//StopGW();
					goto RETURN_001;
				}
				CloseHandle(h[1]);
				h[1]=(HANDLE)_beginthreadex(NULL,0,
					(unsigned int(__stdcall*)(void*))MOThread,
					0,0,0);
				if(h[1]==NULL)
				{
					//if(arg.isMO==0)TerminateThread(h[2],0);
					//StopGW();
					arg.dwStopFlag=0x7e;
					goto RETURN_001;
				}
				break;
			case WAIT_OBJECT_0:	//EventForExit
				AddLog("Get msg to stop GW.\n");
				goto RETURN_001;
				break;
		}//switch(dwRet)
	}//end fo while (1)
RETURN_001:
	if(arg.pCnnGSM->GetState())arg.pCnnGSM->Close();
	::CoUninitialize();
	ExitThread(0);
	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;
}
void GetTime(char* buf)
{
	int ret=0;
	time_t tt;
	struct tm *now;

	time( &tt);
	now = localtime( &tt);
	sprintf( buf, "%d%.2d%.2d%.2d%.2d%.2d",
		now->tm_year,
		now->tm_mon + 1,
		now->tm_mday,
		now->tm_hour,
		now->tm_min,
		now->tm_sec);
}
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+");
}

DWORD GetNByte(char* buffer,BYTE b)
{
    int i; 
    DWORD rt=0; 
	if(b>4)b=4;
    for(i=0;i<b;i++) 
            rt=rt*256+*(unsigned char*)(buffer+i); 
    return rt; 
}

⌨️ 快捷键说明

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