使用boost :: asio在哪里实现协议?

rve*_*rve 8 c++ protocols boost-asio

我正在尝试实现一个简单的串行端口协议.它是这样的:

  1. 丢弃所有数据直到0xff收到
  2. 读标头(节点地址和数据长度,4个字节)
  3. 读取数据(最多64个字节)
  4. 读crc
  5. 处理收到的数据包
  6. 发送回复
  7. 0xff看到时,即使不像在数据中间那样预期,也意味着接收到新的数据包

我可以实现这个使用boost::asio::serial_portboost::asio::read()读取一个字节,并在接收时处理此字节.虽然这有效,但我想知道是否有更多"提升"的方式来做到这一点?

我一直在boost::asio::read_until()寻找阅读0xff,但后来我不知道如何丢弃这些数据.将数据存储在缓冲区中然后不使用缓冲区似乎有点浪费.

我可以使用boost::asio::read_until()读取直到数据包结束,但随后MatchCondition需要访问(缓冲区中的数据包的标头).似乎MatchCondition唯一得到最近收到的第一个和最后一个字节的迭代器.

此外,使用的数据boost::asio::read()最终在a中stream_buf,我必须将接收的数据解析为Packet对象.我可以Packet在一个单独的ParsePacket对象中进行解析,或者以某种方式将它与它集成boost::asio(类似于boost::asio::read(serial, myPacket);where myPacketPacket对象)

0xff在接收的数据中的任何地方看到时,这意味着新的数据包正在启动.因此,当0xff收到它时,它必须忘记任何先前接收的数据并开始接收新的数据包.

我打算使用异步操作并添加超时.

所以,我的问题是:在哪里实现这样的协议?或者更一般地,在哪里使用实现协议boost::asio.我不是在寻找有效的代码,而是建议在何处实现协议以及boost::asio使用哪些功能.

更新:

在这种情况下,没有使用流量控制(硬件或软件).

Sil*_*ker 0

在实现协议时,我之前发现状态机非常有用。

虽然我没有使用过asio,但这种技术可能适用于此。

enum这些可以在 C++ 中作为 an 、循环和 a实现,switch如下所示:

enum States { StateInitial, StateHeader, StateData ... };

States state = StateInitial;
while (1)
{
    char ch = get_byte_function();
    switch (state)
    {
        case StateInitial:
            if (ch == '\xFF')
                state = StateHeader;
            break;

        case StateHeader:
            ...
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要添加更多标志来跟踪协议中的进度。

您可能还想了解boost::statechart如何实现状态机。