如何使用boost::asio::async_read_,直到将外部内存地址用作缓冲区

如何使用boost::asio::async_read_,直到将外部内存地址用作缓冲区,boost,boost-asio,asyncsocket,Boost,Boost Asio,Asyncsocket,async\u read\u until需要一个basic\u streambuf来读取数据。我不想分配额外的内存,而是使用内存地址(来自不允许更改的指定接口)作为目标缓冲区 是否可以使用外部内存地址创建一个streambuf,或者我需要编写一个包装类?最后通过编写我自己的async\u read\u until\u delim类解决了这个问题,该类需要一个内存指针和最大读取字节数。它尽可能接近原始的boost实现,但有一些调整,这将导致更高性能的执行 namespace { template

async\u read\u until
需要一个
basic\u streambuf
来读取数据。我不想分配额外的内存,而是使用内存地址(来自不允许更改的指定接口)作为目标缓冲区


是否可以使用外部内存地址创建一个
streambuf
,或者我需要编写一个包装类?

最后通过编写我自己的
async\u read\u until\u delim
类解决了这个问题,该类需要一个内存指针和最大读取字节数。它尽可能接近原始的boost实现,但有一些调整,这将导致更高性能的执行

namespace {

template<typename read_handler>
class async_read_until_delim
{
public:
    async_read_until_delim(tcp::socket& socket, void* buffer, std::size_t max_read_size_in_bytes,
        char delim, read_handler& handler)
            : m_socket(socket), m_cur(static_cast<char*>(buffer)),
              m_end(static_cast<char*>(buffer) + max_read_size_in_bytes), m_delim(delim),
              m_handler(handler), m_pos(0)
        {
            read_some();
        }
    async_read_until_delim(async_read_until_delim const& other)
        : m_socket(other.m_socket), m_cur(other.m_cur), m_end(other.m_end), m_delim(other.m_delim),
          m_handler(other.m_handler), m_pos(other.m_pos)
        {
        }

    void operator()(boost::system::error_code const& error, std::size_t bytes_transferred)
        {
            if (!error)
            {    
                if (std::find(m_cur, m_end, m_delim) != m_end)
                {
                    m_handler(error, m_pos + bytes_transferred);
                    return;
                }
                else if (m_cur == m_end)
                {
                    m_handler(boost::asio::error::not_found, -1);
                    return;
                }

                m_cur += bytes_transferred;
                m_pos += bytes_transferred;

                read_some();
            }
            else
                m_handler(error, m_pos);
        }

private:
    void read_some()
        {
            m_socket.async_read_some(
                boost::asio::buffer(m_cur, m_end - m_cur), async_read_until_delim(*this));
        }

    tcp::socket&  m_socket;
    char         *m_cur,
                 *m_end;
    char          m_delim;
    read_handler  m_handler;
    std::size_t   m_pos;
};

template<typename read_handler>
inline void do_async_read_until_delim(tcp::socket& socket, void* buffer, std::size_t max_read_size_in_bytes,
    char delim, read_handler& handler)
{
    async_read_until_delim<read_handler>(socket, buffer, max_read_size_in_bytes, delim, handler);
}

} /* anonymous namespace */
名称空间{
模板
类异步读取直到完成
{
公众:
异步读取直到删除(tcp::socket&socket,void*buffer,std::size\u t max\u read\u size\u,以字节为单位),
char delim、read_handler和handler)
:m_socket(socket)、m_cur(static_cast(buffer)),
m_end(静态_cast(buffer)+最大读取大小(以字节为单位),m_delim(delim),
m_处理程序(处理程序),m_位置(0)
{
读一些书;
}
异步读取直到删除(异步读取直到删除常量和其他)
:m_插槽(其他.m_插槽)、m_cur(其他.m_cur)、m_end(其他.m_end)、m_delim(其他.m_delim),
m_handler(其他.m_handler)、m_pos(其他.m_pos)
{
}
void操作符()(boost::system::error\u code const&error,std::size\u t bytes\u transfer)
{
如果(!错误)
{    
if(std::find(mucur,muend,mudelim)!=muend)
{
m_处理程序(错误,m_位置+传输的字节);
返回;
}
else if(m_cur==m_end)
{
m_处理程序(boost::asio::error::not_found,-1);
返回;
}
m_cur+=传输的字节数;
m_pos+=传输的字节数;
读一些书;
}
其他的
m_处理器(错误,m_位置);
}
私人:
空读
{
m_socket.async_read_some(
boost::asio::buffer(mucur,muend-mucur),异步读取直到delim(*this));
}
tcp::socket&m_socket;
char*m_cur,
*穆端;
查姆德里姆;
read_handler m_handler;
std::尺寸m位置;
};
模板
内联void do_async_read_until_delim(tcp::socket&socket,void*缓冲区,std::size_t max_read_size_,以字节为单位),
char delim、read_handler和handler)
{
异步读取直到delim(套接字、缓冲区、最大读取大小(以字节为单位)、delim、处理程序);
}
}/*匿名命名空间*/

因此,我希望它也能对某些人有用。

最终通过编写我自己的
async\u read\u until\u delim
类解决了这个问题,该类需要一个内存指针和最大读取字节数。它尽可能接近原始的boost实现,但有一些调整,这将导致更高性能的执行

namespace {

template<typename read_handler>
class async_read_until_delim
{
public:
    async_read_until_delim(tcp::socket& socket, void* buffer, std::size_t max_read_size_in_bytes,
        char delim, read_handler& handler)
            : m_socket(socket), m_cur(static_cast<char*>(buffer)),
              m_end(static_cast<char*>(buffer) + max_read_size_in_bytes), m_delim(delim),
              m_handler(handler), m_pos(0)
        {
            read_some();
        }
    async_read_until_delim(async_read_until_delim const& other)
        : m_socket(other.m_socket), m_cur(other.m_cur), m_end(other.m_end), m_delim(other.m_delim),
          m_handler(other.m_handler), m_pos(other.m_pos)
        {
        }

    void operator()(boost::system::error_code const& error, std::size_t bytes_transferred)
        {
            if (!error)
            {    
                if (std::find(m_cur, m_end, m_delim) != m_end)
                {
                    m_handler(error, m_pos + bytes_transferred);
                    return;
                }
                else if (m_cur == m_end)
                {
                    m_handler(boost::asio::error::not_found, -1);
                    return;
                }

                m_cur += bytes_transferred;
                m_pos += bytes_transferred;

                read_some();
            }
            else
                m_handler(error, m_pos);
        }

private:
    void read_some()
        {
            m_socket.async_read_some(
                boost::asio::buffer(m_cur, m_end - m_cur), async_read_until_delim(*this));
        }

    tcp::socket&  m_socket;
    char         *m_cur,
                 *m_end;
    char          m_delim;
    read_handler  m_handler;
    std::size_t   m_pos;
};

template<typename read_handler>
inline void do_async_read_until_delim(tcp::socket& socket, void* buffer, std::size_t max_read_size_in_bytes,
    char delim, read_handler& handler)
{
    async_read_until_delim<read_handler>(socket, buffer, max_read_size_in_bytes, delim, handler);
}

} /* anonymous namespace */
名称空间{
模板
类异步读取直到完成
{
公众:
异步读取直到删除(tcp::socket&socket,void*buffer,std::size\u t max\u read\u size\u,以字节为单位),
char delim、read_handler和handler)
:m_socket(socket)、m_cur(static_cast(buffer)),
m_end(静态_cast(buffer)+最大读取大小(以字节为单位),m_delim(delim),
m_处理程序(处理程序),m_位置(0)
{
读一些书;
}
异步读取直到删除(异步读取直到删除常量和其他)
:m_插槽(其他.m_插槽)、m_cur(其他.m_cur)、m_end(其他.m_end)、m_delim(其他.m_delim),
m_handler(其他.m_handler)、m_pos(其他.m_pos)
{
}
void操作符()(boost::system::error\u code const&error,std::size\u t bytes\u transfer)
{
如果(!错误)
{    
if(std::find(mucur,muend,mudelim)!=muend)
{
m_处理程序(错误,m_位置+传输的字节);
返回;
}
else if(m_cur==m_end)
{
m_处理程序(boost::asio::error::not_found,-1);
返回;
}
m_cur+=传输的字节数;
m_pos+=传输的字节数;
读一些书;
}
其他的
m_处理器(错误,m_位置);
}
私人:
空读
{
m_socket.async_read_some(
boost::asio::buffer(mucur,muend-mucur),异步读取直到delim(*this));
}
tcp::socket&m_socket;
char*m_cur,
*穆端;
查姆德里姆;
read_handler m_handler;
std::尺寸m位置;
};
模板
内联void do_async_read_until_delim(tcp::socket&socket,void*缓冲区,std::size_t max_read_size_,以字节为单位),
char delim、read_handler和handler)
{
异步读取直到delim(套接字、缓冲区、最大读取大小(以字节为单位)、delim、处理程序);
}
}/*匿名命名空间*/

因此,我希望它也能对某些人有用。

使用
async\u read\u until()
是一项要求,还是可以使用
async\u read()
?@Sam Miller-不幸的是,使用
async\u read\u until()
似乎是一项要求。我需要读取一个可变的字节数,直到收到一个特定的定界符。使用
async\u read\u until()
是一项要求,还是可以使用
async\u read()
?@Sam Miller-不幸的是,使用
async\u read\u until()
似乎是一项要求。在收到特定的分隔符之前,我需要读取可变的字节数。