简体   繁体   English

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

[英]boost::asio::async_read_until does not read all message

boost::asio::async_read_until does not read all data, and hangs in the middle of the message. 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);
                            }
}

Any idea what's wrong? 知道有什么问题吗? Is not supposed for async_read_until to read until "\\n" is reached? 在到达“ \\ n”之前,不应该让async_read_until读取吗?

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

Whatever you do in response_get() you're not correctly using length . 无论在response_get()做什么,都不能正确使用length This means that any characters received beyond the delimiter ( "\\n" ) are likely also consumed, which means that next read will be lacking the start. 这意味着超过定界符( "\\n" )接收到的所有字符也可能会被消耗掉,这意味着下一个读取将没有开始。

Another issue that might be at play is when your buffer is not dynamic (eg asio::streambuf ) and you didn't reserve enough capacity. 另一个可能起作用的问题是缓冲区不是动态的(例如asio::streambuf )并且您没有保留足够的容量时。 Then the async read will complete when the buffer has been filled, even if the delimiter wasn't received. 这样,即使未收到定界符,当缓冲区已满时,异步读取也将完成。

None of this explains "hang". 这些都不能解释“挂起”。 If you observe a hang, check your server (the sending side) and or networking infrastructure (use a network monitor tool to check that message is actually arriving). 如果发现挂起,请检查服务器(发送方)和/或网络基础结构(使用网络监视工具检查消息是否确实到达)。

Here's a quick fixup of the code to be self-contained: 这是独立代码的快速修正:

#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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM