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

📄 pc2pcview.cpp

📁 VisualC实践与提高——串口通信与工程应用篇代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
									if((uintStxCurNo*1024)<dwFileLen)
									{
										//
										arrSendData[0]=02;//STX,对应02
										arrSendData[1]=(BYTE)(uintStxCurNo%256);
										arrSendData[2]=(BYTE)(uintStxCurNo/256);
										uintSendLen=1+2+1024+1;
										myFile.Seek((uintStxCurNo-1)*1024,CFile::begin);
										myFile.Read(&arrSendData[3],1024);
										bytTemp=0;
										for(i=0;i<=1026;i++)
										{
											bytTemp^=arrSendData[i];
											arrSendDataLast[i]=arrSendData[i];
										}
										arrSendData[1027]=bytTemp;
										arrSendDataLast[1027]=arrSendData[1027];//保存本次发送的数据和数据个数
										uintSendLenLast=uintSendLen;
										Write(arrSendData,1028);
										bytSendStatus=2;
										bytResendCount=0;

									}
									else
									{
										arrSendData[0]=03;//ETX,对应03
										uintSendLen=1+2+2+(dwFileLen-(uintStxCurNo-1)*1024)+1;
										arrSendData[1]=(BYTE)((dwFileLen-(uintStxCurNo-1)*1024)%256);
										arrSendData[2]=(BYTE)((dwFileLen-(uintStxCurNo-1)*1024)/256);
										arrSendData[3]=(BYTE)(uintStxCurNo%256);
										arrSendData[4]=(BYTE)(uintStxCurNo/256);
										myFile.Read(&arrSendData[5],(dwFileLen-(uintStxCurNo-1)*1024));
										bytTemp=0;
										for(i=0;(UINT)i<=uintSendLen-2;i++)
										{
											bytTemp^=arrSendData[i];
											arrSendDataLast[i]=arrSendData[i];
										}
										arrSendData[uintSendLen-1]=bytTemp;
										arrSendDataLast[uintSendLen-1]=arrSendData[uintSendLen-1];//保存本次发送的数据和数据个数
										uintSendLenLast=uintSendLen;
										blnNoTimeout=false;
										bytSendStatus=3;
										Write(arrSendData,uintSendLen);
										bytResendCount=0;
									}
									break;
								}
							case 21://响应是NAK
								{
									
									break;
								}
							case 24://响应是CAN
								{
									DisSend(1);
									break;
								}
							default:
								{
									DisSend(2);//收到无效字符
									return -1;
									break;

								}
							}

							blnNoTimeout=false;      //允许超时
							break;
						}
					case 100://lParam=100,表示事件线程读超时
						{
							if((!blnNoTimeout)&&(bytTimeoutCounter>20))
							{
								DisSend(4);
								bytTimeoutCounter=0;
							}
							else
							{
								if(bytTimeoutCounter<255)//发送传输请求后,延时时间应该长些,
									bytTimeoutCounter++;//以留出让接收端选择保存文件位置需要的时间。

							}
							break;
						}
					}
					break;
				}
			case 2://发送操作的2态
				{
					switch(lParam)
					{
					case EV_RXCHAR://lParam=EV_RXCHAR即1,说明读线程收到数据
						{
							blnNoTimeout=true;
							switch(Detect(1))
							{
							case 0://收到指定数量的字符
								{
									break;
								}
							case 4://超时错误
								{
									DisSend(4);
									blnNoTimeout=false;
									return -1;
									break;
								}

							case 8://无效,输入缓冲区中字符数量为0
								{
									blnNoTimeout=false;
									return 0;
									break;
								}

							}		
							switch(Read(myByte,1))
							{
							case 0:
								{
									//继续后面的操作
									break;
								}
							case 4://超时错误
								{
									DisSend(4);
									blnNoTimeout=false;
									return -1;
									break;
								}
							case 16://读操作失败
								{
									DisSend(16);
									blnNoTimeout=false;
									return -1;
									break;
								}
							}
							switch(myByte[0])
							{
							case 6://响应是ACK
								{
									//发送当前序号的数据

									uintStxCurNo++;//将发送序号加1

									if((uintStxCurNo*1024)<dwFileLen)//能组成完整的1024长的帧,以STX作为数据的起始位
									{
										
										arrSendData[0]=02;
										arrSendData[1]=(BYTE)(uintStxCurNo%256);
										arrSendData[2]=(BYTE)(uintStxCurNo/256);
										uintSendLen=1+2+1024+1;
										myFile.Seek((uintStxCurNo-1)*1024,CFile::begin);
										myFile.Read(&arrSendData[3],1024);
										bytTemp=0;
										for(i=0;i<=1026;i++)
										{
											bytTemp^=arrSendData[i];
											arrSendDataLast[i]=arrSendData[i];
										}
										arrSendData[1027]=bytTemp;
										arrSendDataLast[1027]=arrSendData[1027];//保存本次发送的数据和数据个数
										uintSendLenLast=uintSendLen;
										Write(arrSendData,uintSendLen);
										blnNoTimeout=false;
										bytSendStatus=2;
										bytResendCount=0;

										strDis.Format("已传送(%.0f%%)",(float)((uintStxCurNo+1)*1024)/dwFileLen*100);
										m_pStatus->SetPaneText(0,strDis);     //将传输进度显示在状态栏上

									}
									else//不能组成完整的1024长的帧,以ETX作为数据的起始位
									{
										
										arrSendData[0]=03;//ETX,对应03
										uintSendLen=1+2+2+(dwFileLen-(uintStxCurNo-1)*1024)+1;
										arrSendData[1]=(BYTE)((dwFileLen-(uintStxCurNo-1)*1024)%256);
										arrSendData[2]=(BYTE)((dwFileLen-(uintStxCurNo-1)*1024)/256);
										arrSendData[3]=(BYTE)(uintStxCurNo%256);
										arrSendData[4]=(BYTE)(uintStxCurNo/256);
										myFile.Read(&arrSendData[5],(dwFileLen-(uintStxCurNo-1)*1024));
										bytTemp=0;
										for(i=0;(UINT)i<=uintSendLen-2;i++)
										{
											bytTemp^=arrSendData[i];
											arrSendDataLast[i]=arrSendData[i];
										}
										arrSendData[uintSendLen-1]=bytTemp;
										arrSendDataLast[uintSendLen-1]=arrSendData[uintSendLen-1];//保存本次发送的数据和数据个数
										uintSendLenLast=uintSendLen;
										bytSendStatus=3;
										Write(arrSendData,uintSendLen);

										strDis="已传送(100%)";
										m_pStatus->SetPaneText(0,strDis);     //将传输进度显示在状态条上
										blnNoTimeout=false;
										bytResendCount=0;

									}
									break;
								}
							case 21://响应是NAK
								{


									break;
								}
							case 24://响应是CAN
								{
									
								
									break;
								}
							default:
								{
								
									break;
								}
							}

							blnNoTimeout=false;      //允许超时
							break;
						}
					case 100://lParam=100,表示事件线程读超时
						{
							//AfxMessageBox("time out");
							if(!blnNoTimeout)
							{
								DisSend(4);
							}
							break;
						}
					}
					break;
				}
			case 3://发送操作的3态
				{
					
					switch(lParam)
					{
					case EV_RXCHAR://lParam=EV_RXCHAR即1,说明读线程收到数据
						{
							blnNoTimeout=true;
							switch(Detect(1))
							{
							case 0://收到指定数量的字符
								{
									break;
								}
							case 4://超时错误
								{
									DisSend(4);
									blnNoTimeout=false;
									return -1;
									break;
								}

							case 8://无效,输入缓冲区中字符数量为0
								{
									blnNoTimeout=false;
									return 0;
									break;
								}

							}		
							switch(Read(myByte,1))
							{
							case 0:
								{
									//继续后面的操作
									break;
								}
							case 4://超时错误
								{
									DisSend(4);
									blnNoTimeout=false;
									return -1;
									break;
								}
							case 16://读操作失败
								{
									DisSend(16);
									blnNoTimeout=false;
									return -1;
									break;
								}
							}
							if(myByte[0]==6)//响应是ACK吗?
							{

								myEdit.SetSel(1000000,1000000);
								myEdit.ReplaceSel("传送完毕!\15\12\15\12");

								strDis="已传送完毕";
								m_pStatus->SetPaneText(0,strDis);//将传输进度显示在状态条上
								if(myFile.m_pStream!=NULL)
								{
									myFile.Close();     //关闭打开的文件
								}
								uintStxCurNo=0;      //将发送序号清零
								bytSendStatus=0;
								bytResendCount=0;
								bytRcvStatus=0;
								bytActStatus=10;


							}
							else//响应不是ACK
							{
								if(myByte[0]==21)//响应是NAK吗?
								{
									bytResendCount++;
									if(bytResendCount>3)
									{
										DisSend(8);
										uintStxCurNo=0;//将发送序号清零
										bytActStatus=10;
										bytSendStatus=0;
										bytResendCount=0;

									}
									else
									{
										Write(arrSendDataLast,uintSendLenLast);

										strDis.Format("重发%d次!\15\12",bytResendCount);
										myEdit.SetSel(1000000,1000000);
										myEdit.ReplaceSel(strDis);
									}
								}
								else
								{
									DisSend(2);
									uintStxCurNo=0;//将发送序号清零
									bytActStatus=10;
									bytSendStatus=0;
									bytResendCount=0;
								}

							}

							blnNoTimeout=false;      //允许超时
							break;
						}
					case 100://lParam=100,表示事件线程读超时
						{
							if(!blnNoTimeout)
							{
								DisSend(4);
							}
							break;
						}
					}
					break;
				}
			}

			
			break;
		}
	case 10://接收状态
		{
			switch(bytRcvStatus)
			{
			case 0:
				{
					switch(lParam)
					{
					case EV_RXCHAR://收到数据
						{
							switch(Detect(6))
							{
							case 0://收到指定数量的字符
								{
									break;
								}
							case 4://超时错误
								{
									DisRcv(4);
									return -1;
									break;
								}

							case 8://无效,输入缓冲区中字符数量为0
								{
									return 0;
									break;
								}

							}

							switch(Read(myByte,6))
							{
							case 0://成功读出数据
								{
									//直接跳出switch,继续后面操作
									break;
								}
							case 4://超时错误
								{
									DisRcv(4);
									return -1;
									break;
								}
							case 16://读操作失败
								{
									DisRcv(16);
									return -1;
									break;
								}
							}
							//在这里处理读数据操作,数据存放在myByte中
							for(i=0;i<=5;i++)
							{
								arrRcvData[i]=myByte[i];
							}
							if(arrRcvData[0]==5)
							{
								//计算数据总长度
								uintRcvLen=arrRcvData[5]+7;
							}
							else
							{
								DisRcv(2);
								return -1;
							}
							switch(Read(myByte,arrRcvData[5]+1))
							{
							case 0:
								{
									//直接跳出switch,继续后面操作
									break;
								}
							case 4: 
								{
									DisRcv(4);
									return -1;
									break;
								}
							case 16:
								{
									DisRcv(16);
									return -1;
									break;
								}
							}
							for(i=0;i<=arrRcvData[5];i++)
							{
								arrRcvData[i+6]=myByte[i];//存储数据
							}

							//校验操作
							bytTemp=0;
							for(i=0;(UINT)i<=(uintRcvLen-2);i++)
							{
								bytTemp^=arrRcvData[i];
							}
							if(bytTemp!=arrRcvData[uintRcvLen-1])//若校验出错
							{
								bytResendCount++;
								if (bytResendCount>3)//重试次数大于3
								{
									DisRcv(8);
									return -1;
								}
								else
								{
									arrSendData[0]=21;
									Write(arrSendData,1);
									return -1;

								}
							}
							//至此,经过校验后,完整的数据已经存入arrRcvData[]数组中了
							myEdit.SetSel(1000000,1000000);
							myEdit.ReplaceSel("收到传输请求。\15\12");
							//获取文件名称
							if((myChar=new char[arrRcvData[5]+1])==NULL)
							{
								AfxMessageBox("分配堆内存时出错!");
								//向发送方回应CAN,以取消本次传送
								arrSendData[0]=24;
								Write(arrSendData,1);
								DisRcv(1);
								return -1;
							}

							for(i=0;i<=arrRcvData[5]-1;i++)
							{
								myChar[i]=arrRcvData[i+6];
							}
							myChar[arrRcvData[5]]='\0';
							strDis1=myChar;

							strcpy(myName,myChar);
							strDis="."+strDis1.Right(3);
							strDis+="\0\0";
							strcpy(myExt,strDis);
							delete []myChar;
							
							//打开对话框,提示用户保存文件	
							myFileDlg.m_ofn.lpstrFile=myName;
							myFileDlg.m_ofn.lpstrFilter=myExt;
							if(myFileDlg.DoModal()==IDOK)
							{
								strDis=myFileDlg.GetPathName();
							}
							else
							{
								//向发送方回应CAN,以取消本次传送
								arrSendData[0]=24;
								Write(arrSendData,1);
								DisRcv(1);
								return -1;
							}
							strDis.Replace("\\","\\\\");
							strDis+=myExt;
							if(!myFile.Open(strDis,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary,&e))
							{
								strDis.Format("文件打开时发生异常!错误代码为:%d。",e.m_cause);//文件打开错误处理,错误代码为m_cause
								//strDis+="error";
								AfxMessageBox(strDis);
								bytActStatus=10;                //恢复为接收态
								bytRcvStatus=0;
								bytSendStatus=0;
								return -1;

⌨️ 快捷键说明

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