如何读取数据时长度未知?

问题描述 投票:3回答:1

我目前使用的boost :: ASIO读通过网络连接的数据,但上的图案,我觉得入驻inneficient:

auto listener::read(std::function<void(std::error_code ec, packet packet)> callback) noexcept -> void {
  m_buffer.resize(1);
  m_buffer.shrink_to_fit();

  asio::async_read(*m_socket, asio::buffer(m_buffer), asio::transfer_exactly(1),
                   [&, callback](std::error_code ec, std::size_t length) {
                     const auto available = m_socket->available();
                     packet tmp;
                     tmp.resize(available);
                     asio::async_read(*m_socket, asio::buffer(tmp), asio::transfer_exactly(available));
                     tmp.insert(tmp.begin(), std::make_move_iterator(m_buffer.begin()),
                                std::make_move_iterator(m_buffer.end()));
                     callback(ec, std::move(tmp));
                   });
}

packetstd::vector<unsigned char>

我不知道如何在不临时创建此。我不能在开始调整m_buffer因为我不知道有多少数据即将做。我试图用m_buffer只有拉姆达内调整,以匹配available + 1,但我只是最终失去存储在m_buffer的第一个字节。

有没有更有效的方式期待未知长度的包时,要做到这一点?

c++ c++11 boost-asio
1个回答
1
投票

首先,你可以这样做:

 asio::async_read(*m_socket, asio::buffer(tmp), asio::transfer_exactly(available)); //[1]
 tmp.insert(tmp.begin(), std::make_move_iterator(m_buffer.begin()),
                            std::make_move_iterator(m_buffer.end())); // [2]

在[1]异步操作开始。 async_read立即返回。然后,我们有两个并行操作,所述第一插入到tmp,第二(异步操作)通过一些数据填充tmp。您可以使用同步操作:asio::read代替asio::async_read,前者是阻挡功能,所以当数据被读取insert时才执行。


如果你不想与串联载体,创建临时对象玩等,你可以使用boost :: ASIO :: dynamic_buffer:

struct listener {
 vector<char> m_buffer;
 // others members
};

void listener::read(std::function<void(std::error_code ec, packet p)> callback) 
{
  boost::asio::async_read(m_socket, boost::asio::dynamic_buffer(m_buffer), boost::asio::transfer_exactly(1),
                                                 ^^^^^^^^^^^^^
             [&, callback](std::error_code ec, std::size_t length) 
             {
                 const auto available = m_socket.available();
                 boost::asio::async_read(m_socket, boost::asio::dynamic_buffer(m_buffer), 
                                                                ^^^^^^^^^^^^^
                      boost::asio::transfer_exactly(available),
                   [this,callback](const boost::system::error_code& ec, size_t)
                   {
                      callback(ec, std::move(m_buffer));
                   });
            });
}

m_buffer自动增异步操作。你不是做手工。正如你可以看到我添加了新的处理程序 - >其中被称为callback(ec,move(m_buffer))。当这个处理程序被调用时,我们知道,读操作结束。

© www.soinside.com 2019 - 2024. All rights reserved.