file-type

串口大文件传输优化方案:高效自动报文发送

4星 · 超过85%的资源 | 下载需积分: 50 | 151KB | 更新于2024-10-16 | 91 浏览量 | 47 下载量 举报 1 收藏
download 立即下载
串口传输大文件的方法在电力系统中扮演着关键角色,因为许多设备如故障录波装置和电力微机保护装置需要生成大型文件报告,这些报告记录故障或动作的完整过程,而不仅仅是简单的事件顺序记录。传统的串口通讯,如RS232接口,通常设计用于短距离、低速率的数据传输,对于大文件传输存在局限性。 当前,计算机之间的串行通信广泛应用于各种场景,尽管有许多不同的通讯协议,但在处理大文件传输方面,尚缺乏统一的标准协议。针对这一问题,本文提出了一种基于串口的大文件传输方法,旨在解决大文件在远程设备间的高效、可靠传输。 该方法主要关注于点对点的RS232方式通讯,通常分为三种形式: 1. **直连**:直接使用RS232连接两台设备,适用于近距离传输,例如在同一房间内,传输距离通常不超过15米。这种方式简单易行,但不适用于远距离传输,且文件传输速度受限。 2. **专用通道**:通过RS232与电力调制解调器(MODEM)结合,借助音频电缆和通信介质(如载波、微波或光纤)进行中继,以扩展传输范围。这种方法可以适应较长距离的传输,但可能会引入额外的延迟和不稳定因素。 3. **优化协议设计**:文章的核心内容可能涉及开发一种新型的串口通讯协议或者改进现有的协议,以提高大文件传输的效率和可靠性。这可能包括分块传输、错误检测和纠正机制、以及流量控制策略,确保在串口有限的带宽下,大文件能够被分割成较小的数据包,逐个传输并保持数据完整性。 通过这种方法,不仅可以实现计算机与远程设备之间的大文件自动传输,还能有效提升数据处理的准确性和故障分析的效率。此外,作者姚占东和游大海还可能讨论了该方法的具体实现步骤、性能指标和测试案例,以证明其在实际应用中的可行性。 本文对串口大文件传输技术进行了深入研究,并提供了一种创新的解决方案,这对于电力系统中设备间大文件共享和故障分析具有重要意义,同时也有助于推动串口通讯技术在大数据传输领域的进一步发展。

相关推荐

filetype
#ifndef __WD_PROTOCOL_H__ #define __WD_PROTOCOL_H__ #define SERIALPORT_BUFF_LEN (1024*100) //串口缓存 //区长1M Byte //释放内存时,专用的宏 #define DELETE_OBJ(X) if(x){deletex;x=NULL;} #define DELETE_ARRAYOBJS(x) if(x){delete[]x;x=NULL;} #define CMD_SYN_WORD 0xBBAAFE6B //同步字 #define FILEDATA_LEN 1024*2 //文件数据块长度 typedef enum tagCMDTYPE { CMD_UNKNOWN =0, CMD_FILEINFO =1, CMD_FILEDATA =2, CMD_FILEEOF =3, CMD_FILEINFO_RESP =4,//响应命令 CMD_FILEDATA_RESP =5,//响应命令 CMD_FILEEOF_RESP =6 //响应命令 }CMDTYPE; typedef enum tagCMDSTATE { STATE_UNKNOWN =0, //未知状态 CMD_STATE_OK =1, CMD_STATE_ERROR =2 }CMDSTATE; //帧头-命令消息头 typedef struct tagCMDHEADER { ULONG ulSyncWord; //同步头 CMDTYPE cmdType; CMDSTATE cmdState; ULONG ulPackLen; //包长度,包括数据+校验和 }CMDHEADER; //文件信息结构体,主要发送文件名称和文件大小信息 typedef struct tagFILEINFO { CMDHEADER header; //帧头 UCHAR ucFileName[MAX_PATH]; //文件名称 ULONG ulFileNameLen; //文件名称长度 long lFileLen; //文件长度(单位:字节) ULONG ulCheckSum; //校验和 }FILEINFO; //要发送的文件数据结构体:主要是以固定大小发送文件中的数据 typedef struct tagFILEDATA { CMDHEADER header; //帧头 ULONG ulCheckSum; //校验和 UCHAR *pucBuf; //指向发送缓冲区 }FILEDATA; //文件发送结束命令 typedef struct tagFILEEOF { CMDHEADER header; ULONG ulCheckSum; UCHAR *pucBuf; }FILEEOF; typedef struct tagADDATA { UCHAR ucSyncHeader1; //同步头,0xAABB UCHAR ucSyncHeader2; //同步头,0xAABB float fChan0; //通道0 float fChan1; //通道1 float fChan2; //通道2 float fChan3; //通道3 float fChan4; //通道4 float fChan5; //通道5 float fChan6; //通道6 float fChan7; //通道7 float fChan8; //通道8 float fChan9; //通道9 float fChan10; //通道10 float fChan11; //通道11 UCHAR ucCheckSum; //校验和,前面所有数据的累加和,并取低8位 }ADDATA; ULONG CheckSum(UCHAR *pszBuf,ULONG ulBufLen) { ULONG ulCheckSum =0; for (UINT i=0;i<ulBufLen;i++) { ulCheckSum+=pszBuf[i]; } return ulCheckSum; } #endif //__WD_PROTOCOL_H__
filetype
LONG CSCOMMDlg::OnCommunication(WPARAM ch, LPARAM port) { g_ucRecvBuf[g_ulRecvLen++]=UCHAR(ch); if(g_ulRecvLen>=51) { memcpy(&g_ADData,g_ucRecvBuf,51); //return 1; } // return 1; if(g_ulRecvLen<4) return 1; //1表示接收数据长度不够 ULONG ulCheckSum =0; CMDHEADER header; header = *((CMDHEADER *)g_ucRecvBuf); //如果不相等,将Buffer中的每个数据前移动一个位置 if(CMD_SYN_WORD!= header.ulSyncWord) { memmove(g_ucRecvBuf,g_ucRecvBuf+1,3); return 2;//2表示没有接收到同步字 } if(g_ulRecvLen<sizeof(CMDHEADER)) return 3; //3表示没有接收到帧头 CString strTemp; CString strFileName; char szFilePath[MAX_PATH]={0}; switch(header.cmdType) { case CMD_FILEINFO://文件信息(包括名称,大小)命令 if(g_ulRecvLen<header.ulPackLen) return 4; //没有收到完整的文件信息命令 if(g_ulRecvLen==(sizeof(CMDHEADER)+header.ulPackLen)) { FILEINFO fileInfo; fileInfo=*((FILEINFO *)g_ucRecvBuf); ulCheckSum = CheckSum(fileInfo.ucFileName,fileInfo.ulFileNameLen) +fileInfo.lFileLen; if(ulCheckSum!=fileInfo.ulCheckSum) { fileInfo.header.cmdState = CMD_STATE_ERROR; g_lErrorPackNum++; //strTemp.Format("%d",g_lErrorPackNum); } else { fileInfo.header.cmdState = CMD_STATE_OK; //增加接收文件的计时功能 memset(&g_tRecvBegin,0,sizeof(time_t)); time(&g_tRecvBegin); m_bRecvFileIsBegin = TRUE; } m_nCurFileRecvLen=0; m_nFileRecvLen = fileInfo.lFileLen; //文件长度 fileInfo.header.cmdType =CMD_FILEINFO_RESP; m_Port.WriteToPort((char*)&fileInfo.header,sizeof(CMDHEADER)); memcpy(szFilePath,fileInfo.ucFileName,fileInfo.ulFileNameLen); strFileName.Format("%s",szFilePath); m_strCurFilePath= m_strSaveFileDir+strFileName; if(NULL!=g_file.m_hFile) g_file.Close(); g_file.Open(m_strCurFilePath,CFile::modeCreate|CFile::modeReadWrite); TRACE("1,RECV FILEINFO CMD,File Name = %s,g_ulRecvLen = %d\n", fileInfo.ucFileName,g_ulRecvLen); // if(m_nFileRecvLen1024*1024) // { // strTemp.Format("%0.3fKB",m_nFileRecvLen/1024.0/1024.0); // } // //显示"传输总耗时" // const ULONG ulFrameBytes = g_nBaud/10 -(sizeof(CMDHEADER)+4); // long lComm_TimeSum = m_nFileRecvLen/ulFrameBytes; // //传输总耗时间,单位:秒 // // WORD wHour =0; // WORD wMinute =0; // WORD wSecond =0; // // wSecond = lComm_TimeSum%60; // wMinute = lComm_TimeSum/60%60; // wHour = lComm_TimeSum/60/60%60; // // if((0==wSecond)&&(0==wMinute)&&(0==wHour)) // wSecond =1; // strTemp.Format("%02d:%02d:%02d",wHour,wMinute,wSecond); g_ulRecvLen =0; } break; case CMD_FILEDATA: //发送文件中数据的命令 if(g_ulRecvLen<header.ulPackLen) return 5;//没有收到完整的文件数据帧命令 if(g_ulRecvLen == (sizeof(CMDHEADER)+header.ulPackLen)) { FILEDATA fileData; fileData = *((FILEDATA *)g_ucRecvBuf); fileData.pucBuf = new UCHAR[fileData.header.ulPackLen-4]; memset(fileData.pucBuf,0,fileData.header.ulPackLen-4); memcpy(fileData.pucBuf,g_ucRecvBuf+sizeof(CMDHEADER)+4,fileData.header.ulPackLen-4); ulCheckSum=CheckSum(fileData.pucBuf, fileData.header.ulPackLen-4); if(ulCheckSum!= fileData.ulCheckSum) { fileData.header.cmdState =CMD_STATE_ERROR; g_lErrorPackNum++; strTemp.Format("%d",g_lErrorPackNum); //m_editErrorFrames } else fileData.header.cmdState =CMD_STATE_OK; fileData.header.cmdType = CMD_FILEDATA_RESP; g_file.Write(fileData.pucBuf,fileData.header.ulPackLen-4); //fileData.header.ulPackLen-4, DELETE_ARRAYOBJS(fileData.pucBuf); g_ulRecvLen=0; m_Port.WriteToPort((char*)&fileData.header,sizeof(CMDHEADER)); m_nCurFileRecvLen+=fileData.header.ulPackLen-4; strTemp.Format("%0.2f",(float)m_nCurFileRecvLen/(float)m_nFileRecvLen*100); strTemp+=_T("%"); float step = (float)m_nCurFileRecvLen/(float)m_nFileRecvLen*100; // m_progress.SetPos((int)step); /*if(m_nFileRecvLen1024*1024) { strTemp.Format("%0.3fKB",m_nFileRecvLen/1024.0/1024.0); }*/ } break; case CMD_FILEEOF://文件发送结束命令 if(g_ulRecvLen<header.ulPackLen) return 6;//没有发到完整的文件发送结束命令 if(g_ulRecvLen == (sizeof(CMDHEADER)+header.ulPackLen)) { FILEEOF fileEOF; fileEOF= *((FILEEOF *)g_ucRecvBuf); fileEOF.pucBuf = new UCHAR[fileEOF.header.ulPackLen-4]; memset(fileEOF.pucBuf,0,fileEOF.header.ulPackLen-4); memcpy(fileEOF.pucBuf,g_ucRecvBuf+sizeof(CMDHEADER)+4,fileEOF.header.ulPackLen-4); ulCheckSum = CheckSum(fileEOF.pucBuf,fileEOF.header.ulPackLen-4); if(ulCheckSum!=fileEOF.ulCheckSum) { fileEOF.header.cmdState=CMD_STATE_ERROR; g_lErrorPackNum++; strTemp.Format("%d",g_lErrorPackNum); } else { fileEOF.header.cmdState =CMD_STATE_OK; m_bRecvFileIsBegin = FALSE;//接收文件完成,停止显示时间 } fileEOF.header.cmdType =CMD_FILEEOF_RESP; g_file.Write(fileEOF.pucBuf,fileEOF.header.ulPackLen-4); g_file.Close(); //解决大文件发送时,第二个文件打开错误原因是没“置0”原因 g_file.m_hFile=NULL; DELETE_ARRAYOBJS(fileEOF.pucBuf); g_ulRecvLen=0; m_Port.WriteToPort((char*)&fileEOF.header,sizeof(CMDHEADER)); m_nCurFileRecvLen += fileEOF.header.ulPackLen-4; if(m_nFileRecvLen<=0) { strTemp=_T("0%"); } else { strTemp.Format("%0.2f", (float)m_nCurFileRecvLen/(float)m_nFileRecvLen*100); strTemp+=_T("%"); } if(m_nFileRecvLen1024*1024) { strTemp.Format("%0.3fKB",m_nFileRecvLen/1024.0/1024.0); } } break; //=================处理接收端的响应信息 begin 信息头================= case CMD_FILEINFO_RESP://发送文件信息命令后,发到接收端的响应信息 if(CMD_STATE_OK==header.cmdState) { m_bFileInfoIsOK = TRUE; g_ulRecvLen = 0; g_bIsRecvData = TRUE; } else if(CMD_STATE_ERROR==header.cmdState) { m_bFileInfoIsOK = FALSE; g_ulRecvLen=0; SendFileInfo(); } break; //=================处理接收端的响应信息 文件数据================= case CMD_FILEDATA_RESP://发送文件体命令后,发到接收端的响应信息 if(CMD_STATE_OK==header.cmdState) m_bFileDataIsOK = TRUE; else if(CMD_STATE_ERROR==header.cmdState) m_bFileDataIsOK = FALSE; g_ulRecvLen =0; g_bIsRecvData = TRUE; break; //=================处理接收端的响应信息 文件结尾================= case CMD_FILEEOF_RESP://发送文件尾命令后,发到接收端的响应信息 if(CMD_STATE_OK==header.cmdState) { m_bFileEOFIsOK = TRUE; g_bFileSendEnd = TRUE; } else if (CMD_STATE_ERROR == header.cmdState) { m_bFileEOFIsOK = FALSE; m_bSendFileIsBegin = FALSE; } g_ulRecvLen = 0; g_bIsRecvData = TRUE; break; //====================默认处理================= default:break; } //设置信号量 SetEvent(m_hRecvMsgEvent); return 0; //返回0表示正确 }
duduqq
  • 粉丝: 19
上传资源 快速赚钱