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

📄 infonet.cpp

📁 高速公路收费系统车道软件. 功能: 1 检测公路过往车辆 2 收费过程控制和数据采集 3 车辆信息和图片上传服务器.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// InfoNet.cpp: implementation of the CMessageNet class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "lane_new.h"
#include "InfoNet.h"

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

extern CLane_newApp theApp;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMessageNet::CMessageNet()
{
}

/*	消息通讯网络初始化,绑定通讯协议及IP地址、端口号 */
BOOL CMessageNet::NetworkInitial()
{
	BOOL Ret;
	int LocalPort=GetLocalMessagePort();
	Ret=Create(LocalPort,SOCK_DGRAM,NULL);
	Bind(LocalPort,NULL);
	memset(ServerIP,0,16);
	GetMessageServerIP(ServerIP);
	ServerPort=GetMessageServerPort();
	FatchMesg.Empty();
	for(int i=0;i<FILE_NUMBER+1;i++){
		bReceiveFlag[i]=FALSE;
	}
	if(!Ret){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL_QUIT,ERROR_NETWORK_FAILURE,0);
	}
	return Ret;
}

//	处理Socket接收到的数据
CMessageNet::ProcessReceiveData(unsigned char *pChData, int nDataLen)
{
	try{
	unsigned short CheckSum1=(pChData[nDataLen-5]&0xf)*4096;	//获取接收数据的校验和
	CheckSum1=CheckSum1+(pChData[nDataLen-4]&0xf)*256;
	CheckSum1=CheckSum1+(pChData[nDataLen-3]&0xf)*16;
    CheckSum1=CheckSum1+(pChData[nDataLen-2]&0xf);
	
	int nParityDataLen=nDataLen-5;
	unsigned short CheckSum2=0;
	for(int i=0;i<nParityDataLen;i++){		//计算接收数据的校验和
		CheckSum2=UpDateCRC(CheckSum2,pChData[i]);
	}
	if(CheckSum2!=CheckSum1) return 1;		//校验和错误,返回
	pChData[nParityDataLen]=0xfe;			//将结束符提到校验和前
	if((pChData[3]&1)!=0){					//非I消息(即:命令消息)
		if(pChData[3]==SNRM){				//若是复位命令
			if(RAM_Flag()){
				ResetProcess(VIDAGE_INF,TRANS);	
											//复位TRANS和VIDAGE.INF
			} else {
				ResetProcess(VIDAGE_INF_1,TRANS_1);
			}
			SendPackage(NSA,"",0);			//回送NSA消息给服务器
			return 1;
		}
		if(pChData[3]==CMDR){				//若是命令被拒绝命令
			ResponseCMDR();
			return 1;
		}
		if(((pChData[3]>>1)&0xf)!=0){		//RR消息的1~4位应为0
			return 1;
		}
							//接收RR消息中5、6、7位,即接收计数器内容
		uChServerReceiveIndex=pChData[3]>>5;//服务器要确认的I消息序号
		ResponseRR(pChData[3]);				//响应RR消息
		return 1;
	}
											//此处接收I信息
	uChServerSendIndex=(pChData[3]&0xf)>>1;	//服务器发送的I消息序号
						//若服务器的发送的I消息序号不等于本机的接收序号,则接收错误 
	if(uChServerSendIndex!=uChLocalReceiveIndex){	
		ReceiveError(pChData[3]);
		return 1;
	}
	
//	收到一帧I消息后,用于确认服务器I消息的接收序号加1
	uChLocalReceiveIndex=(uChLocalReceiveIndex+1)%8;
	if(pChData[4]=='1'){					
//	对时消息数据格式:'1',日(2 byte) 月(2 byte) 年(2 byte)
//	时(2 byte) 分(2 byte) 监控模式(1 byte,未用) 秒(2 byte)
		CTimeInfo m_clsTime;
		m_clsTime.AdjustTime(pChData+5);
		TransmitRR();
		return 1;
	}
	
//	消息汇总命令
	if(pChData[4]=='R'){					
		
		CRecord m_clsRecord;
		char chYear[3],ChDayCount[3];
		memset(chYear,0,3);
		memset(ChDayCount,0,3);
		
		memmove(chYear,pChData+5,2);
		memmove(ChDayCount,pChData+7,3);

		m_clsRecord.SetRecordDate(atoi(chYear),atoi(ChDayCount),0,0);
		m_clsRecord.RecordSM();

		TransmitRR();
		return 1;
	}
//	更改发票起命令:格式:VnnnnnnnnnnNNNNNNNNNN.....
//	nnnnnnnnnn、NNNNNNNNNN依次为电脑票、定额票1型车......定额票6型
//	车起号(每种票据10个字节)。
	if(pChData[4]=='V'){
//	特别地:只有在等待更新发票号窗口下才允许更新发票号,因此发票号
//			的更新不能在本函数中进行
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_UPDATE_OK,UPDATE_INVOICE,(LPARAM)pChData+5);
		TransmitRR();
		return 1;
	}

//	开始接收车道数据文件,'D'为文件首块,'S'为中间块(有多次),'F'为文件结束块
	if((pChData[4]=='D')||(pChData[4]=='S')||(pChData[4]=='F')){
		ReceiveFile(pChData+4);
	}
	TransmitRR();
	}
	catch(...){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CMessageNet::ProcessReceiveData()出现异常\n");
		TransmitRR();
	}
	return 0;
}

//	响应上位机的就绪信号,若有数据则发送数据,否则以就绪信号响应
CMessageNet::ResponseRR(unsigned char MessageType)
{
	//若对方用于确认本机I消息的接收序号不等于本方发送窗位置,也不
	//等于本方上一发送窗位置,则出错,发送CMDR消息,若等于本方上一
	//发送窗位置,则说明对方可能未收到上一帧信息,将本方发送窗位置
	//重新定位为上一发送窗位置。
	try{
	if(uChServerReceiveIndex!=uChLocalSendIndex){
		if(uChServerReceiveIndex!=(uChLocalSendIndex-1)%8){
			ReceiveError(MessageType);
			return 1;
		}
		uChLocalSendIndex=(uChLocalSendIndex-1)%8;
	} else {		//若对方用于确认本机I消息的接收序号等于本方发送窗位置
		if(RAM_Flag()){
			AdjustSendPointer(VIDAGE_INF,TRANS);	//本条信息发送成功
		} else {
			AdjustSendPointer(VIDAGE_INF_1,TRANS_1);
		}
	}	
									//将Trans文件中的数据发送出去
	FILE *fp1,*fp2;
	if(RAM_Flag()){
		fp1=fopen(TRANS,"r");
		fp2=fopen(VIDAGE_INF,"r");
	} else {
		fp1=fopen(TRANS_1,"r");
		fp2=fopen(VIDAGE_INF_1,"r");
	}
	if((fp1!=NULL)&&(fp2!=NULL)){
		char tmpStr[MAX_DATA_LENGTH];
		memset(tmpStr,0,MAX_DATA_LENGTH);
		fgets(tmpStr,10,fp2);
		unsigned long TotalPoint=atol(tmpStr);
		fgets(tmpStr,10,fp2);
		memset(tmpStr,0,MAX_DATA_LENGTH);
		fgets(tmpStr,10,fp2);
		unsigned long CurrentPoint=atol(tmpStr);
		fclose(fp2);
		int nLen=0;
		while(1){						//增加于2001年6月25日
			fseek(fp1,CurrentPoint,0);	//找到当前要发送数据的位置
			memset(tmpStr,0,MAX_DATA_LENGTH);
			if(fgets(tmpStr,MAX_DATA_LENGTH,fp1)==0) break;	//读取一行数据
			nLen=strlen(tmpStr)-1;
			if(nLen>0) break;			//合法数据,继续运行
			CurrentPoint=ftell(fp1);	//跳过非法数据
		}
		if(tmpStr[nLen]==0xa) tmpStr[nLen]=0;	//去掉数据末尾的0x0a(换行符)
		unsigned long NextPoint=ftell(fp1);
		fclose(fp1);
		unsigned char MessageType=(uChLocalReceiveIndex<<5)+(uChLocalSendIndex<<1);
		SendPackage(MessageType,tmpStr,nLen);
		uChLocalSendIndex=(uChLocalSendIndex+1)%8;	//本地发送序号++
		if(RAM_Flag()){
			fp2=fopen(VIDAGE_INF,"w");
		} else {
			fp2=fopen(VIDAGE_INF_1,"w");
		}
		if(fp2!=NULL){
			fprintf(fp2,"%ld\n",TotalPoint);
			fprintf(fp2,"%ld\n",NextPoint);
			fprintf(fp2,"%ld\n",CurrentPoint);
			fclose(fp2);
		} else {
			SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"更新文件VIDAGE.INF失败\n");
		}
		bPointEquFlag=FALSE;
	} else {
		TransmitRR();
	}
	}
	catch(...){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CMessageNet::ResponseRR()出现异常\n");
		TransmitRR();
	}
	return 0;
}

//	提示上位机接收错误
CMessageNet::ReceiveError(unsigned char uChMessageType)
{
	char tmpStr[3];
	tmpStr[0]=(char)uChMessageType;
	tmpStr[1]=(uChLocalReceiveIndex<<5)+(uChLocalSendIndex<<1);
	tmpStr[2]=0;
	SendPackage(CMDR,tmpStr,2);
}

//	通过Socket发送数据并缓存发送的数据
CMessageNet::NetSend(unsigned char *pChData, int nDataLen)
{
	try{
	SendTo(pChData,nDataLen,ServerPort,ServerIP);	
	SaveSendData(pChData,nDataLen);
	}
	catch(...){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CMessageNet::NetSend()出现异常\n");
	}
}

//	发送缓存的数据
CMessageNet::SendSaveData()
{
	SendTo(pChSaveData,nSaveDataLen,ServerPort,ServerIP);
}

//	缓存已经发送的数据
CMessageNet::SaveSendData(unsigned char *pChData, int nDataLen)
{
	memset(pChSaveData,0,MAX_DATA_LENGTH);
	for(int i=0;i<nDataLen;i++)
		pChSaveData[i]=pChData[i];
	nSaveDataLen=nDataLen;
}

//	响应上位机的接收错命令:重发缓存的数据
CMessageNet::ResponseCMDR()
{
//	服务器发来CMDR消息,说明本机发送的上一帧数据出错,则将
//	保存在pChSaveData中的数据重新发送
	SendSaveData();
}

//	处理来自上位机的参数文件
void CMessageNet::ReceiveFile(unsigned char *ReceiveData)
{
	char tmpStr[9];
	memset(tmpStr,0,9);
	memmove(tmpStr,ReceiveData+1,8);
	switch(ReceiveData[0]){
	case 'D':
		if(strncmp(tmpStr,"TFRMB",5)==0)
		{
			BeginWriteFile(ReceiveData+1,TFRMB_NEW_INDEX);
		}

		if(strncmp(tmpStr,"COLLECOD",8)==0)
		{
			BeginWriteFile(ReceiveData+1,COLLECOD_INDEX);
		}
		
		if(strncmp(tmpStr,"BLACKCOL",8)==0)
		{
			BeginWriteFile(ReceiveData+1,BLACKCOL_INDEX);
		}
		
		if(strncmp(tmpStr,"BLACKCAR",8)==0)
		{
			BeginWriteFile(ReceiveData+1,BLACKCAR_INDEX);
		}

		if(strncmp(tmpStr,"MONTHCAR",8)==0)
		{
			BeginWriteFile(ReceiveData+1,MONTHCAR_INDEX);
		}

		if(strncmp(tmpStr,"FREECAR",7)==0)
		{
			BeginWriteFile(ReceiveData+1,FREECAR_INDEX);
		}

		if(strncmp(tmpStr,"DELAYS",6)==0)
		{
			BeginWriteFile(ReceiveData+1,DELAYS_INDEX);
		}
		
		break;

	case 'S':
		if(strncmp(tmpStr,"TFRMB",5)==0)
		{
			ContinueWriteFile(ReceiveData+1,TFRMB_NEW_INDEX);
		}

		if(strncmp(tmpStr,"COLLECOD",8)==0)
		{
			ContinueWriteFile(ReceiveData+1,COLLECOD_INDEX);
		}
		
		if(strncmp(tmpStr,"BLACKCOL",8)==0)
		{
			ContinueWriteFile(ReceiveData+1,BLACKCOL_INDEX);
		}
		
		if(strncmp(tmpStr,"BLACKCAR",8)==0)
		{
			ContinueWriteFile(ReceiveData+1,BLACKCAR_INDEX);
		}

		if(strncmp(tmpStr,"MONTHCAR",8)==0)
		{
			ContinueWriteFile(ReceiveData+1,MONTHCAR_INDEX);
		}

		if(strncmp(tmpStr,"FREECAR",7)==0)
		{
			ContinueWriteFile(ReceiveData+1,FREECAR_INDEX);
		}

		if(strncmp(tmpStr,"DELAYS",6)==0)
		{
			ContinueWriteFile(ReceiveData+1,DELAYS_INDEX);
		}
		
		break;

	case 'F':
		
		if(strncmp(tmpStr,"TFRMB",5)==0)
		{
			EndWriteFile(ReceiveData+1,TFRMB_NEW_INDEX);
		}

		if(strncmp(tmpStr,"COLLECOD",8)==0)
		{
			EndWriteFile(ReceiveData+1,COLLECOD_INDEX);
		}
		
		if(strncmp(tmpStr,"BLACKCOL",8)==0)
		{
			EndWriteFile(ReceiveData+1,BLACKCOL_INDEX);
		}
		
		if(strncmp(tmpStr,"BLACKCAR",8)==0)
		{
			EndWriteFile(ReceiveData+1,BLACKCAR_INDEX);
		}

		if(strncmp(tmpStr,"MONTHCAR",8)==0)
		{
			EndWriteFile(ReceiveData+1,MONTHCAR_INDEX);
		}

		if(strncmp(tmpStr,"FREECAR",7)==0)
		{
			EndWriteFile(ReceiveData+1,FREECAR_INDEX);
		}

		if(strncmp(tmpStr,"DELAYS",6)==0)
		{
			EndWriteFile(ReceiveData+1,DELAYS_INDEX);
		}
		
		break;

⌨️ 快捷键说明

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