C++ 提升asio异步读取,直到后面跟着异步读取

C++ 提升asio异步读取,直到后面跟着异步读取,c++,asynchronous,boost,tcp,boost-asio,C++,Asynchronous,Boost,Tcp,Boost Asio,我使用了boost中的异步tcp服务器示例,该示例与我的应用程序的功能非常接近。下面的代码示例是一个完全有效的示例 首先,我启动一个异步读取操作,直到分隔符char。在这种情况下,它是http头完整序列。该请求包含一些有效负载,即“hello world”(11字节)。对于一个简化的示例,我在这里使用lambda处理程序。第一个处理程序的长度为148,它是包含四个字节的分隔符序列的头 缓冲区的大小为159,这是包括有效负载在内的整个请求。到目前为止,一切正常。为了接收有效负载,我调用另一个异步读

我使用了boost中的异步tcp服务器示例,该示例与我的应用程序的功能非常接近。下面的代码示例是一个完全有效的示例

首先,我启动一个异步读取操作,直到分隔符char。在这种情况下,它是http头完整序列。该请求包含一些有效负载,即“hello world”(11字节)。对于一个简化的示例,我在这里使用lambda处理程序。第一个处理程序的长度为148,它是包含四个字节的分隔符序列的头

缓冲区的大小为159,这是包括有效负载在内的整个请求。到目前为止,一切正常。为了接收有效负载,我调用另一个异步读取操作,但从未调用处理程序。我第一次尝试是读取11个字节,但不起作用,所以我尝试只读取两个字节来检查它是否起作用,但它不起作用

streambuf已经包含所有数据,但是为什么不调用异步读取处理程序呢。是否应该立即调用它,因为数据在缓冲区内,或者是否存在对api的任何滥用

编辑1: 最后,我用缓冲区中的字节检查计算要读取的字节。当不需要“true”读取操作时,我使用io_server::post为处理程序添加包装。这似乎是实现这一目标的最佳选择

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class session
  : public std::enable_shared_from_this<session>
{
public:
  session(tcp::socket socket)
    : socket_(std::move(socket))
  {
  }

    boost::asio::streambuf buf;

  void start()
  {
    do_read();
  }

private:
  void do_read()
  {
    auto self(shared_from_this());

    boost::asio::async_read_until(socket_,buf, "\r\n\r\n", [this, self](boost::system::error_code ec, std::size_t length){
        std::istream in(&buf);
        std::cout << length << std::endl;
        std::cout << buf.size() << std::endl;
        in.ignore(length);
        boost::asio::async_read(socket_, buf, boost::asio::transfer_exactly(2), [this, self](boost::system::error_code ec, std::size_t length){
            std::istream in(&buf);
            std::cout << length << std::endl;
        });
    });
  }

  void do_write(std::size_t length)
  {
    auto self(shared_from_this());
    boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
        [this, self](boost::system::error_code ec, std::size_t /*length*/)
        {
          if (!ec)
          {
            do_read();
          }
        });
  }

  tcp::socket socket_;
  enum { max_length = 1024 };
  char data_[max_length];
};

class server
{
public:
  server(boost::asio::io_service& io_service, short port)
    : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
      socket_(io_service)
  {
    do_accept();
  }

private:
  void do_accept()
  {
    acceptor_.async_accept(socket_,
        [this](boost::system::error_code ec)
        {
          if (!ec)
          {
            std::make_shared<session>(std::move(socket_))->start();
          }

          do_accept();
        });
  }

  tcp::acceptor acceptor_;
  tcp::socket socket_;
};

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 2)
    {
      std::cerr << "Usage: async_tcp_echo_server <port>\n";
      return 1;
    }

    boost::asio::io_service io_service;

    server s(io_service, std::atoi(argv[1]));

    io_service.run();
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}
#包括
#包括
#包括
#包括
#包括
使用boost::asio::ip::tcp;
课堂
:public std::从\u中启用\u共享\u
{
公众:
会话(tcp::套接字)
:插座(标准::移动(插座))
{
}
boost::asio::streambuf buf;
void start()
{
你读过吗;
}
私人:
void do_read()
{
自动自我(从_this()共享_);
boost::asio::async_read__until(socket_,buf,“\r\n\r\n”,[this,self](boost::system::error_code ec,std::size_t length){
std::istream in(&buf);

std::cout第二个
async\u read
只读取2个字节。您明确表示要“精确传输2个字节”

您看到的是您不/不想/读取2个字节,因为您已经读取了。您可以进行如下调整:

size_t to_transfer = 2 - std::min(2ul, buf.size());
boost::asio::async_read(socket_, buf, boost::asio::transfer_exactly(to_transfer),
稍微相关的一点是,回调似乎没有被调用,因为您没有显式地刷新std::cout

std::cout << std::unitbuf;
例如,与“客户”类似

输出看起来像

async_accept -> Success
async_read_until -> Success
transferred: 9
buffer: 22
remaining buffer: 13
async_read -> Success
transferred: 0
buffer: 13
Payload: 'mo'
remaining buffer: 11
echo -e 'hello\r\n\r\nmore to come' | netcat localhost 6767
async_accept -> Success
async_read_until -> Success
transferred: 9
buffer: 22
remaining buffer: 13
async_read -> Success
transferred: 0
buffer: 13
Payload: 'mo'
remaining buffer: 11