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

时间:2019-04-10 10:14:41

标签: c++ http boost boost-asio boost-beast

我有一个客户端应用程序,需要从服务器接收http“长时间运行的请求”。我发送一条命令,获得响应的标头后,我只需要接收用\r\n分隔的json数据,直到连接终止。

我设法使boost beast client example适应发送消息,接收标头,解析并从服务器接收响应的情况。但是,我未能找到一种方法来序列化数据以便处理JSON消息。

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

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. 我们已经阅读了标题。为什么我们需要增强野兽而不需要增强asio来读取原始tcp消息?当我尝试同时使用async_read / async_read_some进行读取时,我得到了零大小的无限读取。
  2. parser的文档说(在页面末尾),每条消息都需要一个新的实例,但是在示例中我看不到。
  3. 由于无法读取tcp消息,是否可以将解析器/序列化器数据转换为某种字符串?甚至以FIFO方式将其写入文本文件,以便可以使用某些json库对其进行处理?我不想像示例一样使用另一个套接字。

函数boost::beast::buffers()无法为解析器和序列化器编译,并且对于解析器,没有任何消耗函数,并且序列化器的消耗似乎是针对消息的特定http部分的,如果我发现了,则会触发一个断言为body()做。

除此之外,我还无法通过老式的std::copy从解析器和缓冲区中获取一致的数据块。我似乎不明白如何将数据组合在一起以获取数据流。接收数据时随时在.consume()处使用缓冲区会导致need buffer错误。

我真的很感谢有人解释所有这些如何协同工作的逻辑。

1 个答案:

答案 0 :(得分:0)

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