[英]asio_read_some countinue reading to get all data
I use boost asio async_read_some, the data I want to read STXdataETXlrc, if it were not for lrc I would use async_read_until, how can I continue reading until I get ETXlrc?我用的是boost asio async_read_some,我要读取的数据是STXdataETXlrc,如果不是lrc我就用async_read_until,怎么继续读到ETXlrc? appreciate all the help.
感谢所有帮助。
/huvcbo /huvcbo
From the very sparse information, I'm assuming you are talking in the context of serial comms.从非常稀疏的信息来看,我假设您是在串行通信的背景下交谈。
In that case, the simplest way to get started might be to use Asio's composed read operations (like read
, read_until
etc).在这种情况下,最简单的入门方法可能是使用 Asio 的组合读取操作(如
read
、 read_until
等)。
comm::read_until(sp, buf, '\x03');
With a bit of syntactic sugar you can write more expressively:使用一点语法糖,你可以写得更有表现力:
enum ControlCodes : uint8_t {
STX = 2,
ETX = 3,
};
Eg:例如:
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include <iostream>
namespace comm = boost::asio;
enum ControlCodes : uint8_t {
STX = 2,
ETX = 3,
};
int main(int argc, char** argv) {
comm::io_context ioc;
comm::serial_port sp(ioc, argc > 1 ? argv[1] : "/dev/ttyS6");
sp.set_option(comm::serial_port::baud_rate(115'200));
std::vector<uint8_t> data;
comm::read_until(sp, comm::dynamic_buffer(data), ETX);
}
You could then proceed to to a fixed-length read to get the checksum.然后您可以继续进行固定长度的读取以获取校验和。 More involved overloads of
read_until
allow you to write MatchCondition
instead so you can combine it all in a single call: https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/reference/read_until.html .更多涉及的
read_until
重载允许您改为编写MatchCondition
,以便您可以将它们全部组合在一个调用中: https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/reference/read_until.html 。
Here's an example that uses the boost::regex
overload , that shows the message and whether the checksum verifies:这是一个使用
boost::regex
重载的示例,它显示消息以及校验和是否验证:
Live On Compiler Explorer在编译器资源管理器上运行
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include <boost/regex.hpp>
#include <fmt/ranges.h>
#include <numeric>
namespace comm = boost::asio;
enum ControlCodes : uint8_t {
STX = 2,
ETX = 3,
};
int main(int argc, char** argv) {
comm::io_context ioc;
comm::serial_port sp(ioc, argc > 1 ? argv[1] : "/dev/ttyS6");
sp.set_option(comm::serial_port::baud_rate(115'200));
std::vector<uint8_t> buffer;
auto n = comm::read_until(sp, comm::dynamic_buffer(buffer), boost::regex("\x03."));
auto raw = buffer.data();
bool ok = n >= 3 && *raw == STX;
if (ok) {
auto b = raw + 1;
auto e = b + n - 3; // payload excludes STX, ETX, LRC
auto lrc = accumulate(b, e, uint8_t(0), std::bit_xor<>{});
bool verified = raw[n - 1] == lrc;
fmt::print("Checksum {} bytes verified {}, buffer {::#02x} (expected {:#02x})\n",
n, verified, buffer, lrc);
} else {
fmt::print("Message not wellformed {} bytes buffer {::#02x}\n", n, buffer);
}
}
Tested locally using socat
:使用
socat
在本地测试:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.