我尝试使用boost :: asio和boost :: thread运行异步网络线程。 但async_accept会立即返回错误代码125 - 操作已取消...
附上了问题的最小样本:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
class Server{
public:
Server()
{ }
void listen(unsigned int port)
{
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
boost::asio::ip::tcp::acceptor acceptor(m_io_service, endpoint);
std::cout << "Waiting for incomming connection on port: " << port << std::endl;
acceptor.async_accept(*m_stream.rdbuf(), boost::bind( &Server::handleAccept, this, boost::asio::placeholders::error, boost::ref( acceptor ) ) );
m_listenThread = new boost::thread(boost::bind(&boost::asio::io_service::run, &m_io_service));
}
void stop()
{
m_listenThread->join();
}
private:
void handleAccept(const boost::system::error_code& error, boost::asio::ip::tcp::acceptor& acceptor)
{
std::cout << "receiverd incomming connection" << std::endl;
if(error)
std::cout << "ERROR: " << error.message() << "(" << error.value() << ")" << std::endl;
}
boost::asio::io_service m_io_service;
boost::asio::ip::tcp::iostream m_stream;
boost::thread* m_listenThread;
};
int main(int argc, char *argv[])
{
Server server;
server.listen(10000);
while(1);
}
答案 0 :(得分:3)
acceptor::async_accept
立即返回,在发生错误或连接被接受时调度处理程序的调用(1)
listen()函数正在返回,这导致了acceptor(2)的破坏
当acceptor
(或socket
或deadline_timer
)被销毁时,所有待处理的处理程序都会安排在io_service
上,错误代码为asio::error::operation_aborted
。这是为了满足async_函数的后置条件(即“处理程序将被调用一次,就像通过io_service.post()”)(3)
因此,在第(2)点,正在调度您的处理程序 - 就在代码返回主循环之前。
修复:
确保acceptor
幸存,直到调用处理程序。这是asio异步编程的标准做法。 boost网站上的示例将帮助您理解(稀疏)asio文档。
不要失去希望。我花了很长时间才学会如何正确使用asio,并意识到它是多么强大。