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

时间:2022-09-09 12:54:43

I try to run an async network thread using boost::asio and boost::thread. But the async_accept returns immediately with error code 125 - operation canceled...

我尝试使用boost :: asio和boost :: thread运行异步网络线程。但async_accept立即返回错误代码125 - 操作已取消...

attached I a minimal sample of the Problem:

附上我的问题的最小样本:

#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 个解决方案

#1


3  

acceptor::async_accept returns immediately, scheduling a call of the handler when either there is an error or a connection is accepted (1)

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

the listen() function is returning, which is causing the destruction of the acceptor (2)

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

When an acceptor (or socket, or deadline_timer) is destroyed, all pending handlers are scheduled on the io_service with an error code of asio::error::operation_aborted. This is to satisfy the postconditions of the async_ functions (i.e., "the handler will be called exactly once, as if by io_service.post()") (3)

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

Therefore, at point (2), your handler is being scheduled - just before the code returns to the main loop.

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

To fix:

修理:

ensure that the acceptor survives until the handler has been called. This is standard practice in asio async programming. The examples on the boost website will help you to make sense of the (sparse) asio documentation.

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

Don't lose hope. It took me a long time to learn how to use asio properly, and to realise how fantastically powerful it is.

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

#1


3  

acceptor::async_accept returns immediately, scheduling a call of the handler when either there is an error or a connection is accepted (1)

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

the listen() function is returning, which is causing the destruction of the acceptor (2)

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

When an acceptor (or socket, or deadline_timer) is destroyed, all pending handlers are scheduled on the io_service with an error code of asio::error::operation_aborted. This is to satisfy the postconditions of the async_ functions (i.e., "the handler will be called exactly once, as if by io_service.post()") (3)

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

Therefore, at point (2), your handler is being scheduled - just before the code returns to the main loop.

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

To fix:

修理:

ensure that the acceptor survives until the handler has been called. This is standard practice in asio async programming. The examples on the boost website will help you to make sense of the (sparse) asio documentation.

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

Don't lose hope. It took me a long time to learn how to use asio properly, and to realise how fantastically powerful it is.

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