我正在使用包装类来表示网络连接。我的实现包含一个名为async_connect()
的方法,该方法解析主机/服务并连接到相关端点(如果可能)。像这样:
void tcp::connection::async_connect(std::string const& host, std::string const& service,
protocol_type tcp = protocol_type::v4())
{
std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::async_connect()" << std::endl;
resolver(m_io_service).async_resolve(resolver::query(tcp, host, service),
boost::bind(&connection::resolve_handler, this, _1, _2));
}
我想知道的是,通过完成async_resolve
方法调用处理程序建立连接。
我不确定主线程或工作线程是否用于调用处理程序。因此,我应该调用socket::connect()
(如果该代码将从工作线程执行,这将是最合理的方式)或再次启动异步操作(socket::async_connect()
- 应该在由main执行时使用线程)。
void tcp::connection::resolve_handler(boost::system::error_code const& resolve_error,
tcp::resolver::iterator endpoint_iterator)
{
std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::resolve_handler()" << std::endl;
if (!resolve_error)
{
boost::system::error_code ec;
m_socket.connect(*endpoint_iterator, ec);
}
}
我从控制台输出中观察到我的resolve_handler
是从工作线程调用的。那么,可以在这里拨打socket::connect()
吗?
答案 0 :(得分:2)
IMO在使用asio时坚持使用单个编程模型是件好事。
你可以自由地使用asio的同步(阻塞)调用,你可以调用许多方法(解析,连接等),每个方法都会阻塞,直到结果或错误可用。
但是,如果您正在使用异步编程模型,则主要或调用线程通常在io_service :: run上被阻止,并且从不同的线程调用指定的处理程序(如您所描述的那样)。使用此编程模型时,通常会从处理程序(工作线程)调用下一个 async 方法,因此不要调用socket :: connect,而是调用socket :: async_connect。在我看来,你正试图混合两种不同的模型。我不确定混合两个模型的意义是什么(你的调用线程在io_service :: run上被阻塞)你从处理程序调用同步方法。