将 boost 序列化对象 asio::streambuf 表示转换为 Beast 的动态体 req.body()

Convert boost serialized object's asio::streambuf representation into Beast's DynamicBody req.body()

    // Serialize using boost serialization        
    boost::asio::streambuf binary_buffer;
    boost::archive::binary_oarchive archive(binary_buffer);
    archive << world_map; 

    //beast::buffers_adaptor<boost::asio::streambuf>(binary_buffer);
    req.body().data() = beast::buffers_adaptor<boost::asio::streambuf>(binary_buffer);

我有这段代码,我尝试将 streambuf 转换为 req.body() 以便我可以将它发送到服务器。 查看示例,我无法弄清楚正确的转换是什么。 buffers_adaptor 似乎接受了 MutableBuffer 而不是 asio::streambuf 产生的 ConstBuffer。

我该如何解决这个问题?

对于 dynamic_body,body() 实际上是一个 multi_buffer

所以你需要复制到:

req.body().prepare(binary_buffer.size());
req.body().commit(binary_buffer.size());
auto n = asio::buffer_copy(req.body().data(), binary_buffer.data());

示例:

req.body().prepare(binary_buffer.size());
req.body().commit(binary_buffer.size());
auto n = asio::buffer_copy(req.body().data(), binary_buffer.data());
req.target("http://example.com");
req.method(http::verb::post);
req.set(http::field::host, "example.com");
req.content_length(n);

std::cout << req << std::endl;

版画

POST http://example.com HTTP/1.1
Host: example.coml
Content-Length: 41

22 serialization::archive 18 9 world_map

简化

直接序列化到主体缓冲区会更便宜。您可以使用 Boost Iostreams,例如vector_body:

Live On Coliru

#include <boost/asio/streambuf.hpp>
#include <boost/beast.hpp>
#include <boost/beast/http.hpp>
namespace asio = boost::asio;
namespace beast = boost::beast;
namespace http = beast::http;

#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <iostream>

int main()  {
    http::request<http::vector_body<char> > req;
    {
        namespace io = boost::iostreams;

        using D = io::back_insert_device<std::vector<char> >;
        io::stream_buffer<D> sb(req.body());

        {
            std::ostream os(&sb);
            std::string world_map = "world_map"; // for demo

            boost::archive::text_oarchive archive(os);
            archive << world_map;
        }
    }

    req.target("http://example.com");
    req.method(http::verb::post);
    req.set(http::field::host, "example.com");
    req.content_length(req.body().size());

    std::cout << req << std::endl;
}

版画

POST http://example.com HTTP/1.1
Host: example.com
Content-Length: 41

22 serialization::archive 18 9 world_map