TeraTerm发送二进制串口数据异常问题排查
问题描述
我搭建了VMWare Windows 10虚拟机,采用命名管道实现串口数据传输,并通过TeraTerm连接该管道。开发了一款简单应用程序,每隔几秒发送和接收串口数据,可正常查看虚拟机发送至TeraTerm窗口的串口数据。
但通过TeraTerm(File -> Send file...,勾选binary选项)以文件形式发送二进制数据时,应用程序虽能读取数据,但存在异常:
- 发送的数据:
FF 81 A7 13 64 00 00 90 ... - 读取到的数据:
FFFFFFFF FFFFFF81 FFFFFFA7 13 64 00 00 FFFFFF90 ...
具体表现为部分字节被额外的F填充,且仅前几个字节出现该问题,其余字节正常,但输出中缺失最后几个字节。
代码使用Poco库的串口读写功能,在其他应用中运行正常,这是首次结合虚拟机与TeraTerm进行测试。
补充读取并显示串口数据的代码
char readBuffer[MAX_MESSAGE_SIZE_BYTES]; //2072 int lengthRead = MAX_MESSAGE_SIZE_BYTES; if (m_pSerialPort) { lengthRead = m_pSerialPort->read((char*)readBuffer, lengthRead); if (lengthRead > 0) { CStringA rxBytesReadableHex("RX(bytes): "); size_t row = 0; for (int i = 0; i < lengthRead; i++) { rxBytesReadableHex.AppendFormat("%02X ", readBuffer[i]); row++; if (row == 16) { CString rxBytesReadableHexWide(rxBytesReadableHex); m_listBoxRxData.AddString(rxBytesReadableHexWide); rxBytesReadableHex.Empty(); rxBytesReadableHex.Append(" "); row = 0; } } } }
问题分析与解决建议
问题根源
- 符号扩展导致显示异常:代码中使用有符号的
char类型存储串口读取的字节。Windows下char默认是有符号类型,当读取到0x80-0xFF区间的字节(如0xFF、0x81)时,会被解析为负数值。%02X格式符会将这类负数符号扩展为32位整数,因此显示出FFFFFFFF这类多余的F。 - 剩余字节未显示:代码仅在每读取16个字节时将内容添加到列表框,循环结束后剩余的不足16个字节的内容未被处理,导致输出缺失最后几个字节。
修复方案
- 改用无符号字符类型存储数据:将
char替换为unsigned char,避免符号扩展问题,同时添加剩余字节的处理逻辑:unsigned char readBuffer[MAX_MESSAGE_SIZE_BYTES]; //2072 int lengthRead = MAX_MESSAGE_SIZE_BYTES; if (m_pSerialPort) { lengthRead = m_pSerialPort->read((char*)readBuffer, lengthRead); if (lengthRead > 0) { CStringA rxBytesReadableHex("RX(bytes): "); size_t row = 0; for (int i = 0; i < lengthRead; i++) { rxBytesReadableHex.AppendFormat("%02X ", readBuffer[i]); row++; if (row == 16) { CString rxBytesReadableHexWide(rxBytesReadableHex); m_listBoxRxData.AddString(rxBytesReadableHexWide); rxBytesReadableHex.Empty(); rxBytesReadableHex.Append(" "); row = 0; } } // 处理循环结束后剩余的未显示字节 if (row != 0 && !rxBytesReadableHex.IsEmpty()) { CString rxBytesReadableHexWide(rxBytesReadableHex); m_listBoxRxData.AddString(rxBytesReadableHexWide); } } } - 验证传输链路:从现象来看,TeraTerm的二进制发送功能本身无明显问题。可以用其他串口工具(如串口助手)往命名管道发送相同二进制数据,排查是否为VMware命名管道的传输异常,但优先修复代码的显示问题,因为当前异常大概率由代码类型处理错误导致。
内容的提问来源于stack exchange,提问作者EraticMagician
相关产品推荐
相关产品推荐

