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

📄 picturenet.cpp

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

#include "stdafx.h"
#include "lane_new.h"
#include "PictureNet.h"

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

extern CLane_newApp theApp;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
BOOL CPictureNet::NetworkFlag=TRUE;

CPictureNet::CPictureNet()
{
}

/*	图象通讯网络初始化,绑定IP地址及端口号,发送复位信号到服务器 */
BOOL CPictureNet::NetworkInitial()
{
	BOOL bRet;
	int nLocalPort=GetLocalPicturePort();
	bRet=Create(nLocalPort,SOCK_DGRAM,NULL);
	Bind(nLocalPort,NULL);
	ServerPort=GetPictureServerPort();
	memset(ServerIP,0,16);
	GetPictureServerIP(ServerIP);
	if(bRet){				//若网络初始化成功,向站发送复位命令
		Transmit_SNRM();
	} else {
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL_QUIT,ERROR_NETWORK_FAILURE,0);
	}
	return bRet;
}

/* 车道向站发送复位命令,复位要发送的数据及发送/接收窗口 */
void CPictureNet::Transmit_SNRM()
{
	SendPackage(SNRM,"",0);
	SendMessage(theApp.m_pMainWnd->m_hWnd,WM_STARTUP_TIMER,PICTURE_RESET_TIMER,0);
	NoAckCount=0;
	if(RAM_Flag()){
		ResetProcess(IMG_INDEX,IMG_TRANS);
		ResetProcess(PRIORITY_INDEX,PRIORITY_TRANS);
	} else {
		ResetProcess(IMG_INDEX_1,IMG_TRANS_1);
		ResetProcess(PRI_INDEX_1,PRI_TRANS_1);
	}
	PriorityFlag=FALSE;
}

/* 车道向站发送查询命令 */
void CPictureNet::Transmit_Query()
{
	SendPackage(QUERY,"",0);
	SendMessage(theApp.m_pMainWnd->m_hWnd,WM_STARTUP_TIMER,PICTURE_QUERY_TIMER,0);
	NoAckCount=0;
}

/* 处理来自图象服务器的消息 */
CPictureNet::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;			//将结束符提到校验和前
	NetworkFlag=TRUE;						//网络通讯正常
	SendMessage(theApp.m_pMainWnd->m_hWnd,WM_CLOSE_TIMER,PICTURE_SEND_TIMER,0);
	if((pChData[3]&1)!=0){					//非I消息(即:命令消息)
		if(pChData[3]==NSA){				//站上已复位,等待接收数据
			SendMessage(theApp.m_pMainWnd->m_hWnd,WM_CLOSE_TIMER,PICTURE_RESET_TIMER,0);
			CheckPictureFile();				//判断是否有图片要发送
			return 1;
		}
		if(pChData[3]==CMDR){				//站上接收错误
			ResponseCMDR();
			return 1;
		}
		if(((pChData[3]>>1)&0xf)!=0){		//RR消息的1~4位应为0
//	Add at 2002/12/11  非法字符,发复位命令
			Transmit_SNRM();
			return 1;
		}
							//接收RR消息中5、6、7位,即接收计数器内容
		uChServerReceiveIndex=pChData[3]>>5;//服务器要确认的I消息序号
		ResponseRR(pChData[3]);
		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;
	switch(pChData[4]){						//响应I消息
	case 'E':								//服务器应答结束帧(E帧)
		ResponseFrame_E(pChData,nDataLen);
		return 0;
	case 'Q':								//服务器应答查询命令
		ResponseQuery(pChData, nDataLen);
		return 0;
	default:
//	Add at 2002/12/11  非法字符,发复位命令
		Transmit_SNRM();
		break;
	}
	}
	catch(...){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CPictureNet::ProcessReceiveData()出现异常\n");
		Transmit_SNRM();
	}
	return 0;
}

/* 图象服务器收到I消息后以RR消息应答,车道再发送下一帧 */
CPictureNet::ResponseRR(unsigned char MessageType)
{
	//若对方用于确认本机I消息的接收序号不等于本方发送窗位置,也不
	//等于本方上一发送窗位置,则出错,发送CMDR消息,若等于本方上一
	//发送窗位置,则说明对方可能未收到上一帧信息,将本方发送窗位置
	//重新定位为上一发送窗位置。
	if(uChServerReceiveIndex!=uChLocalSendIndex){
		if(uChServerReceiveIndex!=(uChLocalSendIndex-1)%8){
			ReceiveError(MessageType);
			return 1;
		}
		uChLocalSendIndex=(uChLocalSendIndex-1)%8;
	} else {
		FrameIndex++;				//发送完一帧,帧序号++
	}
	if(FrameIndex==TotalFrame)		//假如图象发送完毕
		Packet_E();
	else
		Packet_F();
	return 0;
}

/*	收到服务器的接收错误命令后本机发复位命令,服务器收到复位命令后
	将接收/发送窗口复位,本机也将接收/发送窗口复位,然后重发数据 */
CPictureNet::ReceiveError(unsigned char uChMessageType)
{
	Transmit_SNRM();				//接收错误,发复位命令
}

//	向图象服务器发送数据,同时缓存发出去的数据
CPictureNet::NetSend(unsigned char *pChData, int nDataLen)
{
	try{
	SendTo(pChData,nDataLen,ServerPort,ServerIP);
	SaveSendData(pChData,nDataLen);		//缓存刚发出的帧
//	若发送的消息为复位消息SNRM或查询消息QUERY,不启动发送定时器,否则
//	查询定时器和复位定时器总被发送定时器优先中断
	if((pChData[3]!=SNRM)&&(pChData[3]!=QUERY)){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_STARTUP_TIMER,PICTURE_SEND_TIMER,0);
	}
	}
	catch(...){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CPictureNet::NetSend()出现异常\n");
		Transmit_SNRM();
	}
}

/* 发送数据缓存区的数据 */
CPictureNet::SendSaveData()
{
	try{
	SendTo(pChSaveDataBuf,dwSaveDataLen,ServerPort,ServerIP);
//	若发送的消息为复位消息SNRM或查询消息QUERY,不启动发送定时器,否则
//	查询定时器和复位定时器总被发送定时器优先中断
	if((pChSaveDataBuf[3]!=SNRM)&&(pChSaveDataBuf[3]!=QUERY)){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_STARTUP_TIMER,PICTURE_SEND_TIMER,0);
	}
	}
	catch(...){
		SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CPictureNet::SendSaveData()出现异常\n");
		Transmit_SNRM();
	}
}

/* 将本次发送的数据存入数据缓存区 */
CPictureNet::SaveSendData(unsigned char *pChData, int nDataLen)
{
	memset(pChSaveDataBuf,0,FRAME_LEN);
	dwSaveDataLen=nDataLen;
	memmove(pChSaveDataBuf,pChData,nDataLen);
}

CPictureNet::ResponseCMDR()
{
	//服务器发来CMDR消息,说明本机发送的上一帧数据出错,则将
	//保存在pChSaveData中的数据重新发送
	static int ErrorCount;
	ErrorCount++;
	if(ErrorCount>3){
		ErrorCount=0;
		Transmit_SNRM();
	} else {
		SendSaveData();
	}
}

/* 车道空闲时每30秒向站上查询是否要上传指定的图片	*/
void CPictureNet::PictureQueryTimerOut()
{
	Transmit_Query();
}

/* 发送一帧数据,若2秒后对方没有响应,则连续每隔2秒发送3帧;若3帧后对方仍无
   响应,认为通讯中断,改发查询命令以便查询通讯是否恢复	*/
void CPictureNet::PictureSendTimerOut()
{
	NoAckCount++;
	if(NoAckCount>=3){				//连续3次无响应,则认为通信中断
		NoAckCount=0;
		Transmit_SNRM();			//改发复位命令
		if(NetworkFlag){
			SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"图象传输网络中断\n");
		}
		NetworkFlag=FALSE;
	} else {
		SendSaveData();
	}
}

/*	网络断开后每隔60秒发送一次复位命令以便判断通讯线路已经恢复 */
void CPictureNet::PictureResetTimerOut()
{
	Transmit_SNRM();
}

/* 判断是否有图片需要上传,若有,上传该图片的S帧,否则查询上位机 */
void CPictureNet::CheckPictureFile()
{
	try{
	struct _finddata_t FileInfo;
	long done1,done2;
	if(RAM_Flag()){
		done1=_findfirst(PRIORITY_INDEX,&FileInfo);
		done2=_findfirst(PRIORITY_TRANS,&FileInfo);
	} else {
		done1=_findfirst(PRI_INDEX_1,&FileInfo);
		done2=_findfirst(PRI_TRANS_1,&FileInfo);
	}
	char IndexFile[PICTURE_NAME_LEN],DataFile[PICTURE_NAME_LEN];
	memset(IndexFile,0,PICTURE_NAME_LEN);
	memset(DataFile,0,PICTURE_NAME_LEN);
	if((done1!=-1L)&&(done2!=-1L)){		//若有要优先发送的图片
		PriorityFlag=TRUE;
		_findclose(done1);
		_findclose(done2);
		if(RAM_Flag()){
			strcpy(IndexFile,PRIORITY_INDEX);
			strcpy(DataFile,PRIORITY_TRANS);
		} else {
			strcpy(IndexFile,PRI_INDEX_1);
			strcpy(DataFile,PRI_TRANS_1);
		}
	} else {
		if(done1!=-1L)
			_findclose(done1);
		if(done2!=-1L)
			_findclose(done2);
		if(RAM_Flag()){
			remove(PRIORITY_INDEX);
			remove(PRIORITY_TRANS);
		} else {
			remove(PRI_INDEX_1);
			remove(PRI_TRANS_1);
		}
		PriorityFlag=FALSE;
		if(RAM_Flag()){
			done1=_findfirst(IMG_INDEX,&FileInfo);
			done2=_findfirst(IMG_TRANS,&FileInfo);
		} else {
			done1=_findfirst(IMG_INDEX_1,&FileInfo);
			done2=_findfirst(IMG_TRANS_1,&FileInfo);

⌨️ 快捷键说明

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