c++ -确保全串行响应
C++ - ensuring full serial response
我正在尝试从硬件设备读取串行响应。我读取的字符串很长,我只需要它的一部分。为了得到我想要的字符串的一部分,我用std::string.substr(x,y);
。然而,我遇到的问题是,有时我会得到一个异常错误,因为我正在读取的缓冲区没有y个字符。下面是我现在用来读取值的代码:
while(1)
{
char szBuff[50+1] = {0};
char wzBuff[14] = {"AT+CSQr"};
DWORD dZBytesRead = 0;
DWORD dwBytesRead = 0;
if(!WriteFile(hSerial, wzBuff, 7, &dZBytesRead, NULL))
std::cout << "Write error";
if(!ReadFile(hSerial, szBuff, 50, &dwBytesRead, NULL))
std::cout << "Read Error";
std:: cout << szBuff;
std::string test = std::string(szBuff).substr(8,10);
std::cout << test;
Sleep(500);
我正在发出命令"AT+CSQ"。这将返回:
N, N
好吧
它返回两个整数值,用逗号分隔,后面跟着一个新行,后面跟着"OK"。
我的问题是,我如何确保在抓取子字符串之前从串行端口读取所有值?根据我的理解,收到的最后一个字符应该是一个新的行
ReadFile
函数的接口似乎为您提供了读取的字节数。如果您知道预期的长度,则应该循环尝试从文件(可能是端口描述符)读取,直到读取预期的字节数。
如果不知道响应的长度,您可能必须读取并检查读缓冲区中是否已读取分隔符令牌(在这种情况下,您的协议似乎表明可以使用新行来确定EOM—消息结束)
如果您可以使用其他库,我会考虑使用boost::asio
和read_until
功能(或您正在使用的任何库中的等效功能)。虽然管理这个的代码不是火箭科学,但在大多数情况下,重新发明轮子是没有意义的。
正如您在上一行中所说的,您知道响应的结束符是一个新的行字符。您需要从串行读取,直到在输入的某个地方接收到新行。从上一个新行到当前新行收到的所有内容都是响应,当前新行之后的所有内容都是下一个响应的一部分。这是通过在循环中读取来实现的,在发现响应时处理每个响应:
char* myBigBuff;
int indexToBuff = 0;
int startNewLine = 0;
while (ReadFile(hSerial, myBigBuff + indexToBuff, 100, &dwBytesRead, NULL))
{
if (strchr(myBigBuff, 'n') != NULL)
{
handleResponse(myBigBuff + startNewLine, indexToBuff + dwBytesRead);
startNewLine = indexToBuff + dwBytesRead;
}
// Move forward in the buffer. This should be done cyclically
indexToBuff += dwBytesRead;
}
这是基本思想。您应该通过您选择的任何方式处理剩余字符(循环缓冲区,简单复制到临时数组等)
您应该使用ReadFile
每个周期将一定数量的字节读入缓冲区。这个缓冲区应该被填满,直到ReadFile
读取0
字节,达到n
或rn
字符,或将缓冲区填满到最大值。
substr
你的字符串,你可以遍历你的字符缓冲区。
例如,while (awaitResponse) {
ReadFile(hSerial, szBuff, 50, &dwBytesRead, NULL);
if (dwBytesRead != 0) {
// move memory from szBuff to your class member (e.g. mySerialBuff)
} else {
// nothing to read
if (buffCounter > 0) {
// process buffer
}
else {
// zero out all buffers
}
}
}
老问题,但我修改了@Eli Iser代码:
while (ReadFile(hSerial, myBigBuff + indexToBuff, 1, &dwBytesRead, NULL)) {
if (strchr(myBigBuff, '-') != NULL || dwBytesRead < 1)
break;
// Move forward in the buffer. This should be done cyclically
indexToBuff += dwBytesRead;
}
if (indexToBuff != 0) {
//Do whatever with the code, it received successfully.
}
- 如何确保C++函数在定义之前声明(如override关键字)
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 使用Unique_ptr确保工厂中的对象唯一
- MESI协议和std::atomic-它是否确保所有写入立即对其他线程可见?
- C++需要帮助从用户那里获得一个整数,并确保它在另外两个整数之间
- 确保流程关闭
- 当服务中的事件被触发时,如何将响应从服务发送回客户端?
- 如何确保接受的C++模板类型使运算符重载?
- C++ 信号和插槽不工作:插槽不响应事件
- 确保编译时的特定 std::array 位置
- NodeJs 服务器充斥着 UDP 广播,不发送响应
- C++关于ENUM的问题。我得到的响应比枚举列表大
- C++ 确保子类为常量提供自定义值
- 应用程序在打开的简历中捕获视频后没有响应
- 使用 cpprest (Casablanca) 返回 PDF 响应
- 确保内存映射页位于内存中
- 确保套装新鲜度的有效方法
- C ++类型特征:确保子类实现方法
- 是否确保 2 个连续的 std::chrono::steady_clock::now() 不相等?
- c++ -确保全串行响应