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

📄 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];
	int i,j;
	BYTE msg_fmt;

	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
		}

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

		try
		{
		switch(GetNByte(buffer+4,4))
		{
		case nSMGP_CONNECT_RESP:
			if(GetNByte(buffer+8,4))
			{
				AddLog("bind to server error for: %d.\n",GetNByte(buffer+8,4));
				arg.isActive=0;
				return ExitFromNetClose;
			}
			else
			{
				AddLog("bind to server ok.\n");
				arg.isActive=1;
			}
		break;
		case nSMGP_TERMINATE_RESP:
			closesocket(arg.s);
			arg.isActive=0;
			return 0;
		break;
		case nSMGP_SUBMIT_RESP:
			SetWindow(-1);
			sprintf(msgbuffer,"%.6x%.8x%.6x",GetNByte(buffer+12,3),GetNByte(buffer+15,4),GetNByte(buffer+19,3));
			dwRet=GetNByte(buffer+22,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)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 nSMGP_ACTIVE_TEST:
			AddLog("get active test here\n");
			PutNByte(buffer+4,4,nSMGP_ACTIVE_TEST_RESP);
			if(i=SendBuffer(buffer))return i;
			arg.isActive=1;
		break;
		case nSMGP_ACTIVE_TEST_RESP:
			if(arg.isDebug)AddLog("active test ok.\n");
			arg.isActive=1;
		break;
		case nSMGP_DELIVER:
			if(buffer[22]==0)//是否是状态报告
			{//deliver process
				sprintf(tmp,"%.6x%.8x%.6x",GetNByte(buffer+12,3),GetNByte(buffer+15,4),GetNByte(buffer+19,3));
				msg_fmt=(BYTE)buffer[23];
				if(msg_fmt==0||msg_fmt==3||msg_fmt==4||msg_fmt==15)
				for(i=0;i<(BYTE)buffer[80];i++)//状态报告标志后面就是1字节的长度标志
					sprintf(msgbuffer+i*2,"%.2x",//长度标志后面就是信息体
					(BYTE)(buffer[81+i]));
				else
				{
					if(j=UCS2toGB(buffer+81,strSQL,(BYTE)buffer[80]))
					for(i=0;i<j;i++)
						sprintf(msgbuffer+i*2,"%.2x",(BYTE)(strSQL[i]));
					else msgbuffer[0]=0;
					msg_fmt=15;
				}
				sprintf(strSQL,"exec sp_insert_mo '%s','%.21s',0x%s,%d,'%.21s',%d",
					tmp,//ismg_id
					buffer+38,//src_termid
					msgbuffer,//msg
					msg_fmt,//msg_format
					buffer+59,//dst_termid
					arg.iChannelNum//channel number.
					);

				AddResp("MO",0,"%d,%s,%.21s,0x%s,%d,%.21s\n",
					arg.iChannelNum,//channel number.
					tmp,//ismg_id
					buffer+38,//src_termid
					msgbuffer,//msg
					msg_fmt,//msg_format
					buffer+59//dst_termid
					);
			}
			else
			{//state report process
				sprintf(tmp,"%.6x%.8x%.6x",GetNByte(buffer+84,3),GetNByte(buffer+87,4),GetNByte(buffer+91,3));
				sprintf(strSQL,"EXEC SP_STATE_REPORT %d,'%s','%.21s','%.7s','%.3s'",
					arg.iChannelNum,
					tmp,//ismg_id
					buffer+38,//dst_termid,长度为21字节
					buffer+162,//state
					buffer+174);//err code
				AddResp("Status",0,"%d,%s,%.21s,%.7s,%.3s,%.21s\n",
					arg.iChannelNum,
					tmp,//ismg_id
					buffer+38,//dst_termid,长度为21字节
					buffer+162,//state
					buffer+174,//error code
					buffer+59);//src_termid
			}
			if(arg.isDebug>1)AddLog("%s\n",strSQL);
			arg.pCnnGSM->Errors->Clear();
			arg.pCnnGSM->Execute((char*)strSQL,NULL,adExecuteNoRecords);
			PutNByte(buffer,4,26);//length
			PutNByte(buffer+4,4,nSMGP_DELIVER_RESP);//cmd
			memcpy(buffer+12,tmp,10);//ismg_id
			PutNByte(buffer+22,4,0);//result
			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];
	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=nSMGP_CONNECT;
		tm.dwSequence=0;
		if(dwRet=SendData(&tm,arg.pCnnGSM))
		{	
			if(dwRet==ExitFromNetClose)return 0;
			tm.dwCommand=nSMGP_TERMINATE;
			dwRet=SendData(&tm,arg.pCnnGSM);
			if(dwRet==ExitFromNetClose)return 0;
			tm.dwCommand=nSMGP_CONNECT;
			dwRet=SendData(&tm,arg.pCnnGSM);
			SleepEx(arg.iSelectInterval,1);
			if(dwRet)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%2==0)
	h[2]=(HANDLE)_beginthreadex(NULL,0,(unsigned int(__stdcall*)(void*))MTThread,0,0,0);
	dwRecv=dwSend=0;
	tm.dwCommand=nSMGP_ACTIVE_TEST;
	while(1)
	{
		if(arg.isMO%2==0)
		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))
				{
					ResetEvent(arg.hGW);
					TerminateThread(h[2],0);
					TerminateThread(h[1],0);
					goto RETURN_001;
				}
#endif
				if((dwRecv>(arg.dwRecv+5)&&arg.isMO)||dwSend>arg.dwSend+50)
				{
					if(arg.isDebug)
						AddLog("No data, thread 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.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();
					goto RETURN_001;
				}
				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)
				{
					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();
					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 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 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; 
}

int SendBuffer(char* buffer,int buf_len)
{
	int i,j;
	if(arg.s<1||arg.dwStopFlag)return ExitFromNetClose;
	i=j=0;
#if ONESECTION1
	EnterCriticalSection(&(arg.syc1));
#endif
	while(i<buf_len)
	{
		j=send(arg.s,buffer+i,buf_len-i,0);
		if(j<1)
		{
			AddLog("send socket error for: %d\n",WSAGetLastError());
			if(i>0)AddBinLog(buffer,i,1);
#if ONESECTION1
			LeaveCriticalSection(&(arg.syc1));
#endif
			return ExitFromNetClose;
		}

		i+=j;
	}
#if ONESECTION1
	LeaveCriticalSection(&(arg.syc1));
#endif
	AddBinLog(buffer,i,0);
	return 0;
}
int SendBuffer(char* buffer)
{
	int i,j,buf_len;
	if(arg.s<1||arg.dwStopFlag)return ExitFromNetClose;
	i=j=0;
	buf_len=(int)GetNByte(buffer,4);
#if ONESECTION1
	EnterCriticalSection(&(arg.syc1));
#endif
	while(i<buf_len)
	{
		j=send(arg.s,buffer+i,buf_len-i,0);
		if(j<1)
		{
			AddLog("send socket error for: %d\n",WSAGetLastError());
			if(i>0)AddBinLog(buffer,i,1);
#if ONESECTION1
			LeaveCriticalSection(&(arg.syc1));
#endif

⌨️ 快捷键说明

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