试图理解 boost::beast 多缓冲区 [英] Trying to understand the boost::beast multibuffer

查看:115
本文介绍了试图理解 boost::beast 多缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Beast websocket 示例将数据存储在多缓冲区中:

<块引用>

实现使用一个或多个字符数组的序列大小不一.附加字符数组对象附加到适应字符大小变化的序列序列.

查看界面时,我并不完全清楚它是如何工作的.如果我阅读描述,它可以被视为一个缓冲区数组.但似乎输出只是一个数据块.这是否意味着一个或多个数组"仅适用于内部结构?

在示例代码中,数据按如下方式读入缓冲区:m_websocketStream.async_read(m_buffer.....

每个 async_read 操作是否会创建一个新的内部缓冲区.

如果是这样,那另一端如何解释.例如.如何将其读入 std::string 或 std::vector.

查看源数据时,data() 返回 const_buffer_type,这是一个前向声明.

对于数据成员,帮助信息提供了以下信息,没有太大帮助:

<块引用>

用于将输入序列表示为缓冲区列表的类型.使用 const_buffers_type = implementation_defined;

该定义似乎来自头文件 boost/asio/buffer.hpp,它也包含在内.然而,整体结构对我来说有些模糊.

我只是想了解如何将数据作为字节处理或将其转换为 std::string.

尝试了以下方法,但这也是不允许的:

std::string( boost::asio::buffer_cast(m_buffer.data()),boost::asio::buffer_size(m_buffer.data()));

谁能给我一点启发?

解决方案

data() 返回满足ConstBufferSequence (http://www.boost.org/doc/libs/1_65_0/doc/html/boost_asio/reference/ConstBufferSequence.html).prepare() 返回满足 MutableBufferSequence 要求的对象 (http://www.boost.org/doc/libs/1_65_0/doc/html/boost_asio/reference/MutableBufferSequence.html)>

beast 中的所有动态缓冲区都满足 DynamicBuffer 的要求,描述在 http://www.boost.org/doc/libs/develop/libs/beast/doc/html/beast/concepts/DynamicBuffer.html

如果要将缓冲区序列转换为字符串,则需要遍历每个元素并将其单独附加到字符串.这样的函数可能如下所示:

template标准::字符串to_string(ConstBufferSequence const& 缓冲区){std::string s;s.reserve(boost::asio::buffer_size(buffers));for(boost::asio::const_buffer b : 缓冲区)s.append(boost::asio::buffer_cast(b),boost::asio::buffer_size(b));返回 s;}

或者,如果你想避免缓冲区复制,你可以使用类似 beast::flat_buffer 的东西,它保证所有缓冲区序列的长度为 1.像这样:

内联标准::字符串to_string(beast::flat_buffer const& buffer){返回 std::string(boost::asio::buffer_cast(野兽::buffers_front(buffer.data())),boost::asio::buffer_size(buffer.data()));}

有关缓冲区的更多信息,请参见 http://www.boost.org/doc/libs/1_65_0/doc/html/boost_asio/overview/core/buffers.html

The Beast websocket example stores the data in a multibuffer:

The implementation uses a sequence of one or more character arrays of varying sizes. Additional character array objects are appended to the sequence to accommodate changes in the size of the character sequence.

When looking at the interface it is not completely clear to me how it works. If I read the descriptions it can be seen as an array of buffers. But it seems the output is only a single chunk of data. Does this mean the "one or more arrays" are only applicable to the internal structure ?

In the example code the data is read into the buffer as follows: m_websocketStream.async_read(m_buffer.....

Does each async_read operation creates a new internal buffer.

If this is the case, how to interpret it at the other end. E.G. how to read it into a std::string or std::vector.

When looking into the sources data() returns const_buffer_type, which is a forward declaration.

For the data member the help information provides the following info, which is not of much help:

The type used to represent the input sequence as a list of buffers. using const_buffers_type = implementation_defined;

The definition seems to come from the header file boost/asio/buffer.hpp which is included as well. The overall structure however is somewhat obfuscating to me.

I just try to understand how to handle the data as bytes or convert it to as std::string.

Tried the following, but this is also not allowed:

std::string( boost::asio::buffer_cast<const char*>(m_buffer.data()) ,boost::asio::buffer_size(m_buffer.data()) );

Anyone who can enlighten me a little ?

解决方案

data() returns an object meeting the requirements of ConstBufferSequence (http://www.boost.org/doc/libs/1_65_0/doc/html/boost_asio/reference/ConstBufferSequence.html). prepare() returns an object meeting the requirements of MutableBufferSequence (http://www.boost.org/doc/libs/1_65_0/doc/html/boost_asio/reference/MutableBufferSequence.html)

All of the dynamic buffers in beast meet the requirements of DynamicBuffer, described in http://www.boost.org/doc/libs/develop/libs/beast/doc/html/beast/concepts/DynamicBuffer.html

If you want to convert a buffer sequence into a string you need to loop over each element and append it to the string individually. Such a function might look like this:

template<class ConstBufferSequence>
std::string
to_string(ConstBufferSequence const& buffers)
{
    std::string s;
    s.reserve(boost::asio::buffer_size(buffers));
    for(boost::asio::const_buffer b : buffers)
        s.append(boost::asio::buffer_cast<char const*>(b),
            boost::asio::buffer_size(b));
    return s;
}

Alternatively, if you want to avoid the buffer copy you can use something like beast::flat_buffer which guarantees that all the buffer sequences will have length one. Something like this:

inline
std::string
to_string(beast::flat_buffer const& buffer)
{
    return std::string(boost::asio::buffer_cast<char const*>(
        beast::buffers_front(buffer.data())),
            boost::asio::buffer_size(buffer.data()));
}

For more information on buffers, see http://www.boost.org/doc/libs/1_65_0/doc/html/boost_asio/overview/core/buffers.html

这篇关于试图理解 boost::beast 多缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆