This commit is contained in:
coco
2026-07-03 16:05:30 +08:00
commit df489d5640
1101 changed files with 779140 additions and 0 deletions
@@ -0,0 +1,425 @@
# 通信工具
<cite>
**本文档引用的文件**
- [SComPort.cpp](file://cpp\Tools\SComPort.cpp)
- [SComPort.h](file://h\SComPort.h)
- [TcpClient.cpp](file://cpp\Tools\TcpClient.cpp)
- [TcpClient.h](file://h\TcpClient.h)
- [Zmodem.cpp](file://cpp\Tools\Zmodem.cpp)
- [Zmodem.h](file://h\Zmodem.h)
- [FileTransfer.cpp](file://cpp\Tools\FileTransfer.cpp)
- [FileTransfer.h](file://h\FileTransfer.h)
- [FileTransfer_crul.cpp](file://cpp\Tools\FileTransfer_crul.cpp)
- [FileTransfer_crul.h](file://h\FileTransfer_crul.h)
- [HttpDownload.cpp](file://cpp\Tools\HttpDownload.cpp)
- [HttpDownload.h](file://h\HttpDownload.h)
- [Constant.h](file://h\Constant.h)
- [CtrlProtocolDef.h](file://h\CtrlProtocolDef.h)
</cite>
## 目录
1. [引言](#引言)
2. [串口通信模块](#串口通信模块)
3. [TCP通信模块](#tcp通信模块)
4. [Zmodem文件传输协议](#zmodem文件传输协议)
5. [文件传输协作机制](#文件传输协作机制)
6. [HTTP下载功能](#http下载功能)
7. [应用场景与调用示例](#应用场景与调用示例)
8. [最佳实践](#最佳实践)
9. [结论](#结论)
## 引言
GeomativeStudio中的通信工具集成了多种通信方式,包括串口通信、TCP通信、Zmodem协议文件传输和HTTP下载功能。这些工具为设备连接、固件升级和数据同步等关键功能提供了底层支持。本文档详细分析了这些通信模块的实现机制与使用方法。
## 串口通信模块
### SComPort类实现
`SComPort`类封装了Windows平台下的串口通信功能,提供了异步读写、超时控制和多线程安全处理等特性。
**串口初始化与配置**
`SComPort`类通过`OpenComm`方法初始化串口连接,设置通信参数如波特率(115200)、数据位(8位)、奇偶校验(无)和停止位(1位)。该类使用重叠I/O(Overlapped I/O)实现异步通信,确保主线程不会被阻塞。
```mermaid
classDiagram
class CSComPort {
+CString m_szComName
+HANDLE m_hCom
+HWND m_hOwnerWnd
+long m_lCommID
+DCB m_dcbBlock
+char m_aWriteBuffer[WRITEBUFFER_SIZE]
+int m_iWriteSize
+char m_aReadBuffer[READBUFFER_SIZE]
+int m_iReadSize
+DWORD m_dwBLThreadID
+HANDLE m_hBLThread
+BOOL m_bIsDetBreakFun
+BOOL m_bIsScanBreak
+DWORD m_dwFactdata
+FILE* m_Log
+CSComPort()
+CSComPort(HWND hOwnerWnd, long lCommID)
+~CSComPort()
+BOOL FindComName(CStringArray* pStringArray)
+BOOL OpenComm(CString szComName)
+void SetOwnerWnd(HWND hOwnerWnd)
+void SetCommID(long lCommID)
+void CloseComm()
+BOOL ReceiveDataDirectly(char* pDataBuff, int* iDataSize)
+BOOL SendDataDirectly(char* pDataBuff, int iDataSize)
+void SetScanBreakSign(BOOL bIsScanBreak)
+void ClearCommSendBuff()
+void ClearCommReceiveBuff()
+BOOL ZmodemReceiveDataDirectly(char* pDataBuff, int* iDataSize)
+BOOL ZmodemSendDataDirectly(char* pDataBuff, int iDataSize)
+static UINT SComPortDetectBreakThreadFun(LPVOID pParam)
}
```
**Diagram sources**
- [SComPort.h](file://h\SComPort.h#L14-L73)
- [SComPort.cpp](file://cpp\Tools\SComPort.cpp#L31-L285)
**异步读写机制**
`ReceiveDataDirectly``SendDataDirectly`方法实现了异步读写功能。读取操作首先通过`ClearCommError`检查输入缓冲区中的数据量,然后使用`ReadFile`函数进行异步读取。如果`ReadFile`立即返回`ERROR_IO_PENDING`,则通过`GetOverlappedResult`等待操作完成。
**超时控制**
通信超时通过`GetOverlappedResult`的最后一个参数`TRUE`实现,该参数指示函数应阻塞直到操作完成或超时。日志记录功能通过`fopen`打开日志文件"LOG\\commLog.txt"实现,所有发送和接收的数据都会被记录。
**多线程安全处理**
`SComPort`类通过`m_hBLThread`线程监控串口连接状态。`SComPortDetectBreakThreadFun`线程函数定期尝试重新打开串口,如果失败则通过`SendMessage`通知所有者窗口串口已断开。
**Section sources**
- [SComPort.cpp](file://cpp\Tools\SComPort.cpp#L306-L403)
- [SComPort.cpp](file://cpp\Tools\SComPort.cpp#L527-L576)
- [SComPort.cpp](file://cpp\Tools\SComPort.cpp#L225-L256)
## TCP通信模块
### TcpClient类实现
`CTcpClient`类实现了TCP客户端通信功能,支持连接管理、数据收发和异常重连。
```mermaid
classDiagram
class CTcpClient {
+CString m_strIP
+WORD m_wPort
+SOCKET m_sockClient
+int m_iRcvBuf
+int m_iSndBuf
+bool m_bIsConnect
+char* m_pClearRcvBuf
+CTcpClient()
+~CTcpClient()
+bool InitailTcp()
+bool ConnectServer(CString strAddr, WORD wPort)
+bool ConnectToServer(CString strIP, WORD wPort)
+int SendData(const char* pData, int wLen)
+bool CloseConnect()
+bool GetConnectStatus()
+bool ReConnect()
+bool RecvData(char* pData, int iLen, int& iActualLen)
+bool Disconnect()
+bool ClearRecvBuffer()
}
```
**Diagram sources**
- [TcpClient.h](file://h\TcpClient.h#L18-L75)
- [TcpClient.cpp](file://cpp\Tools\TcpClient.cpp#L26-L39)
**连接管理**
`InitailTcp`方法初始化套接字,设置套接字选项如`SO_LINGER`、接收/发送缓冲区大小和`SO_KEEPALIVE``ConnectServer`方法建立与服务器的连接,`CloseConnect`方法关闭连接并释放资源。
**数据收发**
`SendData`方法使用`send`函数发送数据,`RecvData`方法使用`select`函数实现非阻塞接收。`select`函数检查套接字是否有数据可读,超时时间为25毫秒。
**异常重连**
`ReConnect`方法实现了异常重连机制。当连接断开时,先调用`CloseConnect`关闭现有连接,然后重新初始化套接字并通过`ConnectToServer`重新连接。
**Section sources**
- [TcpClient.cpp](file://cpp\Tools\TcpClient.cpp#L48-L97)
- [TcpClient.cpp](file://cpp\Tools\TcpClient.cpp#L101-L130)
- [TcpClient.cpp](file://cpp\Tools\TcpClient.cpp#L252-L278)
## Zmodem文件传输协议
### Zmodem类实现
`Zmodem`类实现了Zmodem协议,用于在串口连接上进行可靠的文件传输。
```mermaid
classDiagram
class Zmodem {
+CSComPort* port
+FILE* file
+long file_length
+long byte_count
+int file_count
+char file_name[128]
+char buffer[BUFFSIZE]
+unsigned long m_FileSize
+int m_ByteTransfer
+char m_WriteBuff[8192]
+int m_WriteBuffLength
+int m_nBufReadIndex
+FILE* zmodemLog
+DWORD dwBegin
+char cReadLog[2048]
+int nLogLength
+int nIndex
+Zmodem(CSComPort* rs232_port)
+~Zmodem()
+BOOL Send(char* files[])
+BOOL Receive(CString Path)
+BOOL SendCancelString()
+int GetTransferPosit()
+int GetFileSize()
}
```
**Diagram sources**
- [Zmodem.h](file://h\Zmodem.h#L31-L142)
- [Zmodem.cpp](file://cpp\Tools\Zmodem.cpp#L33-L56)
**帧结构解析**
Zmodem协议使用多种帧类型进行通信,包括`ZRQINIT``ZRINIT``ZFILE``ZDATA``ZEOF``ZFIN``ReadHeader`方法解析接收到的帧头,`SendBinaryHeader`方法发送二进制帧头。
**错误校验**
Zmodem协议使用CRC-16或CRC-32进行错误校验。`Crc16``Crc32`类用于计算数据的校验和。`SendDataFrame`方法在发送数据帧时包含校验信息。
**断点续传机制**
`ReceiveSingleFile`方法实现了断点续传功能。当接收文件时,如果文件已存在且大小与远程文件相同,则发送`ZRPOS`帧请求从上次中断的位置继续传输。
**Section sources**
- [Zmodem.cpp](file://cpp\Tools\Zmodem.cpp#L128-L127)
- [Zmodem.cpp](file://cpp\Tools\Zmodem.cpp#L558-L774)
- [Zmodem.cpp](file://cpp\Tools\Zmodem.cpp#L253-L258)
## 文件传输协作机制
### FileTransfer与FileTransfer_crul协作
`FileTransfer``FileTransfer_crul`类共同实现了设备与主机间的文件传输功能。
```mermaid
classDiagram
class FileTransfer {
+CSComPort* port
+FILE* file
+long file_length
+long byte_count
+int file_count
+char file_name[128]
+char buffer[BUFFSIZE]
+FileTransfer()
+virtual ~FileTransfer()
+virtual void error(char* fmt, ...)
+virtual void status(char* fmt, ...)
+virtual BOOL Send(char* files[]) = 0
+virtual BOOL Receive(CString Path) = 0
}
class FileTransfer_crul {
+CURL* m_pCrEasyHandl
+CURL* m_pCrPuteasyHandl
+FILE* m_pLog
+CString m_strUrl
+CString m_strSavePath
+CString m_strSaveName
+bool m_bIsNeedProgress
+bool m_bIsNeedErrInfo
+int m_nTimeOut
+bool m_bIsGobalInitial
+bool m_bIsHttpsFlag
+bool m_bIsSSLCertify
+FileTransfer_crul()
+virtual ~FileTransfer_crul()
+bool Inital()
+void UnInital()
+void SetOption(EnOptFlag enFlag, CString strInfo, bool bFlag = false)
+bool DownloadFile()
+DOUBLE GetFileSize()
+bool GetUrlResConValild()
+void InitalLogInfo()
+static size_t WriteToFile(void* ptr, size_t size, size_t nmemb, void* userp)
+static int xferinfo(void* p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
+static size_t WriteToBuff(void* ptr, size_t size, size_t nmemb, void* userp)
+static size_t WriteFuncForUrlTest(void* ptr, size_t size, size_t nmemb, void* userp)
+void PrintLog(CString strLog)
}
FileTransfer <|-- Zmodem : "extends"
FileTransfer_crul --> CURL : "uses"
```
**Diagram sources**
- [FileTransfer.h](file://h\FileTransfer.h#L26-L48)
- [FileTransfer_crul.h](file://h\FileTransfer_crul.h#L55-L110)
- [FileTransfer_crul.cpp](file://cpp\Tools\FileTransfer_crul.cpp#L24-L62)
**协作流程**
`FileTransfer`作为基类定义了文件传输的接口,`Zmodem`类继承自`FileTransfer`并实现了基于串口的文件传输。`FileTransfer_crul`类使用libcurl库实现HTTP/HTTPS文件下载功能。
**Section sources**
- [FileTransfer.cpp](file://cpp\Tools\FileTransfer.cpp#L28-L47)
- [FileTransfer_crul.cpp](file://cpp\Tools\FileTransfer_crul.cpp#L151-L281)
## HTTP下载功能
### HttpDownload类实现
`HttpDownload`类实现了HTTP协议下载功能,支持多线程下载和断点续传。
```mermaid
classDiagram
class HttpDownload {
+BOOL m_bSupportResume
+BOOL m_bResume
+BOOL m_bStop
+BOOL m_bIsUseFile
+BOOL m_bFileLocked
+BOOL m_bAddSize
+DWORD m_dwDownloadSize
+int runningThreadCnt
+int nComplete
+CString m_strServer
+CString m_strObject
+CString m_strSavePath
+CString m_strTempSavePath
+CString m_strReferer
+CString m_strDownloadUrl
+CTime m_TimeLastModified
+UINT m_nPort
+FILE* globalFile
+DWORD m_dwFileSize
+int m_dwThreadCnt
+InforImpl inforImpl
+NewTask TaskInfo
+CSocket m_pSocket
+HttpDownload()
+virtual ~HttpDownload()
+void FreeMemory()
+void SetStop(bool stop)
+BOOL StartHttpTask(NewTask task)
+bool CreateNewFile(CString fileName, DWORD size)
+void GetInfofromDevision()
+bool GetInfofromTemp(CString filename)
+void CreateInforImpl(CString str)
+UINT SendRequest(BOOL bHead = false)
+UINT GetInfo(LPCTSTR lpszHeader, DWORD& dwContentLength, DWORD& dwStatusCode, CTime& TimeLastModified)
+BOOL ParseURL(CString str)
+CTime GetTime(LPCTSTR lpszTime)
+bool WriteInfoToFile()
+bool WriteToFile(CString filePath, DWORD pos, char* buffer, int len)
+void CreateThread()
+bool Download(int index)
}
class InforImpl {
+CString server
+CString object
+CString savePath
+DWORD fileSize
+int threadCnt
+DWORD downloadSize
+FromToImpl* fromToImpl
}
class FromToImpl {
+DWORD from
+DWORD to
}
class NewTask {
+CString server
+CString object
+UINT port
+UINT threadCnt
+CString savepath
}
HttpDownload --> InforImpl : "contains"
HttpDownload --> FromToImpl : "contains"
HttpDownload --> NewTask : "uses"
```
**Diagram sources**
- [HttpDownload.h](file://h\HttpDownload.h#L69-L154)
- [HttpDownload.cpp](file://cpp\Tools\HttpDownload.cpp#L26-L46)
**多线程下载**
`StartHttpTask`方法首先发送HTTP请求获取文件大小,然后根据文件大小和线程数分配下载任务。每个线程负责下载文件的一部分,通过`Range`头指定下载范围。
**断点续传**
`GetInfofromTemp`方法从临时配置文件中读取已下载的文件信息,实现断点续传功能。如果文件大小发生变化,则重新开始下载。
**Section sources**
- [HttpDownload.cpp](file://cpp\Tools\HttpDownload.cpp#L68-L219)
- [HttpDownload.cpp](file://cpp\Tools\HttpDownload.cpp#L104-L209)
## 应用场景与调用示例
### 设备连接
```mermaid
sequenceDiagram
participant 应用程序
participant SComPort
participant 串口硬件
应用程序->>SComPort : OpenComm("COM1")
SComPort->>串口硬件 : CreateFile("\\\\.\\COM1")
串口硬件-->>SComPort : 返回句柄
SComPort->>SComPort : 设置DCB参数
SComPort-->>应用程序 : 返回TRUE
```
**Diagram sources**
- [SComPort.cpp](file://cpp\Tools\SComPort.cpp#L127-L223)
### 固件升级
```mermaid
sequenceDiagram
participant 应用程序
participant Zmodem
participant SComPort
应用程序->>Zmodem : Send(["firmware.bin"])
Zmodem->>SComPort : SendDataDirectly(ZRQINIT帧)
SComPort->>Zmodem : 接收响应
Zmodem->>Zmodem : 发送ZFILE帧
Zmodem->>SComPort : 发送数据帧
loop 数据传输
SComPort->>Zmodem : 接收数据帧
Zmodem->>SComPort : 发送ZACK确认
end
Zmodem->>SComPort : 发送ZFIN帧
SComPort->>Zmodem : 接收ZFIN响应
Zmodem-->>应用程序 : 返回TRUE
```
**Diagram sources**
- [Zmodem.cpp](file://cpp\Tools\Zmodem.cpp#L62-L127)
### 数据同步
```mermaid
sequenceDiagram
participant 应用程序
participant TcpClient
participant 服务器
应用程序->>TcpClient : ConnectToServer("192.168.1.100", 8080)
TcpClient->>服务器 : 建立TCP连接
服务器-->>TcpClient : 连接成功
TcpClient-->>应用程序 : 返回TRUE
应用程序->>TcpClient : SendData(同步数据)
TcpClient->>服务器 : 发送数据
服务器-->>TcpClient : 返回响应
TcpClient-->>应用程序 : 返回发送字节数
```
**Diagram sources**
- [TcpClient.cpp](file://cpp\Tools\TcpClient.cpp#L101-L130)
## 最佳实践
### 线程同步
使用Windows API的同步机制,如`CreateThread``WaitForSingleObject`,确保多线程环境下的数据一致性。
### 资源释放
在析构函数中释放所有分配的资源,如关闭文件句柄、套接字和线程句柄。
### 异常处理
使用`try-catch`块捕获异常,并通过日志记录详细的错误信息。
## 结论
GeomativeStudio的通信工具集成功了多种通信方式,为设备连接、固件升级和数据同步提供了可靠的基础。通过深入分析这些模块的实现机制,开发者可以更好地理解和使用这些工具,提高开发效率和系统稳定性。