(非提升)ASIO `操作中止`错误
(non-boost) ASIO `Operation aborted` error
我正在学习 asio,这是我遇到的错误的最小可重现示例。错误是 Operation aborted
(代码 125)。我完全不知道为什么会这样。感谢您的帮助。
#include <asio.hpp>
#include <asio/ip/tcp.hpp>
#include <iostream>
#include <memory>
class connection : public std::enable_shared_from_this<connection>
{
asio::io_context& context;
const char* host;
public:
connection(const char* host, asio::io_context& context) : context(context), host(host)
{}
void start()
{
auto self = shared_from_this();
asio::ip::tcp::resolver resolver{context};
resolver.async_resolve(asio::ip::tcp::v4(), host, "http", [self](asio::error_code er, asio::ip::tcp::resolver::results_type endpoint){
if(!er)
{
std::cout << endpoint->endpoint().address() << ' ' << endpoint->endpoint().port() << std::endl;
} else {
throw std::runtime_error("Error resolving host: " + er.message() + std::to_string(er.value()));
}
});
}
};
int main()
{
asio::io_context context;
std::make_shared<connection>("www.google.com", context)->start();
context.run();
}
ASIO 的一个基本 属性 是 I/O 对象必须比它们的异步操作长寿。 I/O 个对象的析构函数取消未完成的异步操作。
在start()
中创建解析器并启动异步解析操作。然后,解析器立即被破坏,从而取消操作。
一个解决方案是让 resolver
成为 connection
的数据成员,这样它就足够长了:
class connection : public std::enable_shared_from_this<connection>
{
asio::io_context& context;
const char* host;
asio::ip::tcp::resolver resolver;
public:
connection(const char* host, asio::io_context& context) : context(context), host(host), resolver(context)
{}
void start()
{
auto self = shared_from_this();
resolver.async_resolve(asio::ip::tcp::v4(), host, "http", [self](asio::error_code er, asio::ip::tcp::resolver::results_type endpoint){
if(!er)
{
std::cout << endpoint->endpoint().address() << ' ' << endpoint->endpoint().port() << std::endl;
} else {
throw std::runtime_error("Error resolving host: " + er.message() + std::to_string(er.value()));
}
});
}
};
或者,将 resolver
放在它自己的共享指针后面,并在处理程序中捕获共享指针:
class connection : public std::enable_shared_from_this<connection>
{
asio::io_context& context;
const char* host;
public:
connection(const char* host, asio::io_context& context) : context(context), host(host)
{}
void start()
{
auto self = shared_from_this();
auto resolver = std::make_shared<asio::ip::tcp::resolver>(context);
resolver->async_resolve(asio::ip::tcp::v4(), host, "http", [self, resolver](asio::error_code er, asio::ip::tcp::resolver::results_type endpoint){
if(!er)
{
std::cout << endpoint->endpoint().address() << ' ' << endpoint->endpoint().port() << std::endl;
} else {
throw std::runtime_error("Error resolving host: " + er.message() + std::to_string(er.value()));
}
});
}
};
我正在学习 asio,这是我遇到的错误的最小可重现示例。错误是 Operation aborted
(代码 125)。我完全不知道为什么会这样。感谢您的帮助。
#include <asio.hpp>
#include <asio/ip/tcp.hpp>
#include <iostream>
#include <memory>
class connection : public std::enable_shared_from_this<connection>
{
asio::io_context& context;
const char* host;
public:
connection(const char* host, asio::io_context& context) : context(context), host(host)
{}
void start()
{
auto self = shared_from_this();
asio::ip::tcp::resolver resolver{context};
resolver.async_resolve(asio::ip::tcp::v4(), host, "http", [self](asio::error_code er, asio::ip::tcp::resolver::results_type endpoint){
if(!er)
{
std::cout << endpoint->endpoint().address() << ' ' << endpoint->endpoint().port() << std::endl;
} else {
throw std::runtime_error("Error resolving host: " + er.message() + std::to_string(er.value()));
}
});
}
};
int main()
{
asio::io_context context;
std::make_shared<connection>("www.google.com", context)->start();
context.run();
}
ASIO 的一个基本 属性 是 I/O 对象必须比它们的异步操作长寿。 I/O 个对象的析构函数取消未完成的异步操作。
在start()
中创建解析器并启动异步解析操作。然后,解析器立即被破坏,从而取消操作。
一个解决方案是让 resolver
成为 connection
的数据成员,这样它就足够长了:
class connection : public std::enable_shared_from_this<connection>
{
asio::io_context& context;
const char* host;
asio::ip::tcp::resolver resolver;
public:
connection(const char* host, asio::io_context& context) : context(context), host(host), resolver(context)
{}
void start()
{
auto self = shared_from_this();
resolver.async_resolve(asio::ip::tcp::v4(), host, "http", [self](asio::error_code er, asio::ip::tcp::resolver::results_type endpoint){
if(!er)
{
std::cout << endpoint->endpoint().address() << ' ' << endpoint->endpoint().port() << std::endl;
} else {
throw std::runtime_error("Error resolving host: " + er.message() + std::to_string(er.value()));
}
});
}
};
或者,将 resolver
放在它自己的共享指针后面,并在处理程序中捕获共享指针:
class connection : public std::enable_shared_from_this<connection>
{
asio::io_context& context;
const char* host;
public:
connection(const char* host, asio::io_context& context) : context(context), host(host)
{}
void start()
{
auto self = shared_from_this();
auto resolver = std::make_shared<asio::ip::tcp::resolver>(context);
resolver->async_resolve(asio::ip::tcp::v4(), host, "http", [self, resolver](asio::error_code er, asio::ip::tcp::resolver::results_type endpoint){
if(!er)
{
std::cout << endpoint->endpoint().address() << ' ' << endpoint->endpoint().port() << std::endl;
} else {
throw std::runtime_error("Error resolving host: " + er.message() + std::to_string(er.value()));
}
});
}
};