如何将 boost::beast 中的序列化数据转换为字符串,以便以 FIFO 方式处理它?

How can I convert serialized data in boost::beast to a string so that I could process it in a FIFO manner?

我有一个客户端应用程序,我需要从服务器接收 http "long running requests"。我发送一个命令,在得到响应的 header 之后,我必须只接收 json 由 \r\n 分隔的数据,直到连接终止。

我设法调整 boost beast client example 来发送消息并接收 header 并解析它并从服务器接收响应。但是,我未能找到一种方法来序列化数据,以便我可以处理 json 消息。

问题的最接近演示可以在 this relay example 中找到。在该示例中(p 是解析器,sr 是序列化器,input 是套接字输入流,output 是套接字输出流),在读取 http header,我们有一个从服务器连续读取的循环:

do
{
    if(! p.is_done())
    {
        // Set up the body for writing into our small buffer
        p.get().body().data = buf;
        p.get().body().size = sizeof(buf);

        // Read as much as we can
        read(input, buffer, p, ec);

        // This error is returned when buffer_body uses up the buffer
        if(ec == error::need_buffer)
            ec = {};
        if(ec)
            return;

        // Set up the body for reading.
        // This is how much was parsed:
        p.get().body().size = sizeof(buf) - p.get().body().size;
        p.get().body().data = buf;
        p.get().body().more = ! p.is_done();
    }
    else
    {
        p.get().body().data = nullptr;
        p.get().body().size = 0;
    }

    // Write everything in the buffer (which might be empty)
    write(output, sr, ec);

    // This error is returned when buffer_body uses up the buffer
    if(ec == error::need_buffer)
        ec = {};
    if(ec)
        return;
}
while(! p.is_done() && ! sr.is_done());

这里有几点我不明白:

  1. 我们读完了 header。为什么我们需要 boost beast 而不是 boost asio 来读取原始 tcp 消息?当我尝试这样做时(同时使用 async_read/async_read_some),我得到了零大小的无限读取。
  2. parser 的文档说(在页面末尾)每条消息都需要一个新实例,但我在示例中没有看到。
  3. 由于 tcp 消息读取不起作用,有没有办法将 parser/serializer 数据转换为某种字符串?甚至以 FIFO 方式将它写入文本文件,以便我可以使用某些 json 库来处理它?我不想像示例那样使用另一个套接字。

函数 boost::beast::buffers() 无法为解析器和序列化器编译,并且对于解析器没有使用函数,序列化器的使用似乎是针对消息的特定 http 部分,它会触发断言如果我为 body().

这样做

除此之外,我也未能使用 old-school std::copy 从解析器和缓冲区获取一致的数据块。我似乎不明白如何将数据组合在一起以获得数据流。在接收数据时随时使用 .consume() 的缓冲区会导致 need buffer 错误。

我非常感谢有人解释所有这些应该如何协同工作的逻辑。

buf在哪里?您可以直接读入 std::string 。调用string.resize(N),将buffer_body::value_type中的指针和大小设置为string.data()string.size()