boost :: asio :: async_read_until不会读取所有消息 [英] boost::asio::async_read_until does not read all message
问题描述
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屋!