Trying to understand the boost::beast multibuffer

拟墨画扇 提交于 2019-12-07 13:13:30

问题


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 ?


回答1:


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




回答2:


In the latest versions of Beast, there is now the function buffers_to_string which will do this for you in a single function call.



来源:https://stackoverflow.com/questions/46132570/trying-to-understand-the-boostbeast-multibuffer

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!