📄 picturenet.cpp
字号:
// 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 + -