在一个线程中提升asio运行io_service

时间:2016-04-20 14:10:46

标签: c++ multithreading boost boost-asio

我尝试使用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);
}

1 个答案:

答案 0 :(得分:3)

acceptor::async_accept立即返回,在发生错误或连接被接受时调度处理程序的调用(1)

listen()函数正在返回,这导致了acceptor(2)的破坏

acceptor(或socketdeadline_timer)被销毁时,所有待处理的处理程序都会安排在io_service上,错误代码为asio::error::operation_aborted 。这是为了满足async_函数的后置条件(即“处理程序将被调用一次,就像通过io_service.post()”)(3)

因此,在第(2)点,正在调度您的处理程序 - 就在代码返回主循环之前。

修复:

确保acceptor幸存,直到调用处理程序。这是asio异步编程的标准做法。 boost网站上的示例将帮助您理解(稀疏)asio文档。

不要失去希望。我花了很长时间才学会如何正确使用asio,并意识到它是多么强大。