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);
}
}
知道什么是错的吗?在达到“\ n”之前,不应该让async_read_until读取吗?
答案 0 :(得分:0)
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();
}