C++ 如何将boost::beast中的序列化数据转换为字符串,以便以FIFO方式进行处理?
我有一个客户端应用程序,需要从服务器接收http“长时间运行的请求”。我发送了一个命令,在得到响应的头之后,我只需要接收由C++ 如何将boost::beast中的序列化数据转换为字符串,以便以FIFO方式进行处理?,c++,http,boost,boost-asio,boost-beast,C++,Http,Boost,Boost Asio,Boost Beast,我有一个客户端应用程序,需要从服务器接收http“长时间运行的请求”。我发送了一个命令,在得到响应的头之后,我只需要接收由\r\n分隔的json数据,直到连接终止 我设法适应了发送消息和接收消息头、解析消息和接收来自服务器的响应。然而,我未能找到一种方法来序列化数据,以便处理json消息 关于这个问题的最接近的例子可以在中找到。在该示例中(p是一个解析器,sr是一个序列化程序,input是一个套接字输入流,output是一个套接字输出流),在读取http头之后,我们有一个从服务器连续读取的循环:
\r\n
分隔的json数据,直到连接终止
我设法适应了发送消息和接收消息头、解析消息和接收来自服务器的响应。然而,我未能找到一种方法来序列化数据,以便处理json消息
关于这个问题的最接近的例子可以在中找到。在该示例中(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());
有几件事我不明白:
boost::beast::buffers()
失败,对于解析器,没有使用函数,序列化程序的使用似乎是针对消息的特定http部分,如果我为body()
执行此操作,则会触发断言
除此之外,我还无法使用老式的std::copy
从解析器和缓冲区获得一致的数据块。我似乎不明白如何将数据组合在一起以获得数据流。在接收数据的任何时候使用.consume()
消耗缓冲区都会导致需要缓冲区
错误
如果有人能解释一下所有这些应该如何协同工作的逻辑,我将不胜感激。buf在哪里?您可以直接读入
std::string
。调用string.resize(N)
,并将buffer\u body::value\u type
中的指针和大小设置为string.data()
和string.size()
buf在哪里?您可以直接读入std::string
。调用string.resize(N)
,并将buffer\u body::value\u type中的指针和大小设置为string.data()
和string.size()
IIUYC,它所做的唯一更改是用字符串替换buf
。但这不是我遇到麻烦的地方。我在序列化程序后遇到问题。与将序列化程序写入套接字不同(如我从http_中继复制的示例所示),我希望它转到字符串/视图。你之前提到过分块,这是一个合理的担忧。特别是,在我所有将任何内容转换为字符串的尝试中,我都会重复部分数据。你能不能写一段代码来代替write(output,sr,ec)
转换为将sr
转换为字符串的内容?是否要将HTTP消息转换为字符串?使用OperatorTanks,Vinnie。我想我现在明白它是怎么工作的了。我不需要序列化程序。我误解了文件。序列化程序不是必需的,因为我不想提交到套接字。我只需要解析器。一旦我在解析器模板参数中使用了string\u body
,一切都变得简单,一切都很好。剩下的唯一问题是,由于它是分块的,而且数据流永远不会结束,解析器内容一直在无限期地增长。有没有办法清除/使用其字符串内容?(除了重新创建连接之外)我发现的唯一清晰的函数是针对单个body对象的,而不是解析器中的所有对象。问题是由于某种原因,在body()
中,所有的终止符\r\n
都不存在。我可以通过使用有效负载_size()
绕过这个问题,在这里我读取一个body,如果可以解析,就用json解析它,然后清除body()字符串。不知道为什么终结者正在消失。我可以接受这一点,只要消息/读取回调不会合并,否则会破坏json解析。如果我做得不对,请告诉我。最好的。您不会看到分块编码分隔符,因为Beast的解析器会在将数据附加到字符串之前删除它们。正如我已经说过的,如果您想增量解析一个永无止境的响应,请使用buffer\u body
。IIUYC,它所做的唯一更改是将buf
替换为字符串。但这不是我遇到麻烦的地方。我在序列化程序后遇到问题。与将序列化程序写入套接字不同(如我从http_中继复制的示例所示),我希望它转到字符串/视图。你之前提到过分块,这是一个合理的担忧。特别是,在我所有将任何内容转换为字符串的尝试中,我都会重复部分数据。你能不能写一段代码来代替write(output,sr,ec)
转换为将sr
转换为字符串的内容?是否要将HTTP消息转换为字符串?使用OperatorTanks,Vinnie。我想我现在明白它是怎么工作的了。我不需要序列化程序。我误解了文件。序列化程序不是必需的,因为我不想提交到套接字。我只需要解析器。有一次,我在解析器te中使用了字符串\u body