boost::asio::async_read_until 不会读取所有消息

boost::asio::async_read_until does not read all message

本文关键字:读取 消息 until asio async read boost      更新时间:2023-10-16

boost::asio::async_read_until 不会读取所有数据,而是在消息中间挂起。

    boost::asio::async_read_until(socket, response, "n", boost::asio::placeholders::error));
                        [&](const boost::system::error_code &err2, std::size_t lenght)
                        {
                            RUN_CHECK;
                            if (!err2)
                            {
                                RUN_CHECK;
                                std::string r =  this->response_get();
    /*
    .. do stuff here
    */
                            }
                            else
                            {
                                report_error(err2);
                            }
}

知道出了什么问题吗?在到达""之前不应该让async_read_until读取?

                  std::string r = this->response_get();

无论您在response_get()中做什么,您都没有正确使用length。这意味着任何超出分隔符("n"(的字符也可能被消耗,这意味着下一次读取将缺少开始。

另一个可能起作用的问题是当您的缓冲区不是动态的(例如 asio::streambuf (,并且您没有预留足够的容量。然后,异步读取将在缓冲区填充后完成,即使未收到分隔符也是如此。

这些都不能解释"挂起"。如果观察到挂起,请检查服务器(发送端(和/或网络基础结构(使用网络监视器工具检查邮件是否实际到达(。

下面是要自包含的代码的快速修复:

#include <boost/asio.hpp>
#include <iostream>
#define RUN_CHECK                                                                                                      
    do {                                                                                                               
        std::cout << "Here:" << __LINE__ << "n";                                                                      
    } while (0)
struct X {
    boost::asio::io_service io;
    boost::asio::ip::tcp::socket socket{io};
    X() {
        socket.connect({ {}, 6767 });
    }
    boost::asio::streambuf response;
    void foo() {
        boost::asio::async_read_until(socket, response, "n",
              [&](const boost::system::error_code &ec, std::size_t length) {
                  RUN_CHECK;
                  if (!ec) {
                      RUN_CHECK;
                      std::string r = this->response_get(length);
                      /*
                      .. do stuff here
                      */
                  } else {
                      report_error(ec);
                  }
              });
    }
    std::string response_get(std::size_t length) {
        std::string result;
        std::copy_n(boost::asio::buffers_begin(response.data()), length, back_inserter(result));
        return result;
    }
    void report_error(boost::system::error_code ec) {
        std::cout << "Error: " << ec.message() << "n";
    }
};
int main() {
    X x;
    x.foo();
    x.io.run();
}