boost :: asio :: async_read_until不会读取所有消息 [英] boost::asio::async_read_until does not read all message

查看:72
本文介绍了boost :: asio :: async_read_until不会读取所有消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

boost :: asio :: async_read_until无法读取所有数据,并且挂在消息中间.

boost::asio::async_read_until does not read all data, and hangs in the middle of the message.

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

有什么想法吗?在到达"\ n"之前,不应该让async_read_until读取吗?

Any idea what's wrong? Is not supposed for async_read_until to read until "\n" is reached?

推荐答案

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

无论您在 response_get()中执行什么操作,都不会正确地使用 length 正确.这意味着超过定界符("\ n" )接收到的所有字符也可能会被消耗掉,这意味着下一个读取将缺少开始.

Whatever you do in response_get() you're not correctly using 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.

另一个可能正在起作用的问题是当缓冲区不是动态的(例如 asio :: streambuf )并且您没有保留足够的容量时.这样,即使没有收到定界符,异步读取也将在缓冲区已满时完成.

Another issue that might be at play is when your buffer is not dynamic (e.g. asio::streambuf) and you didn't reserve enough capacity. 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();
}

这篇关于boost :: asio :: async_read_until不会读取所有消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆