【问题标题】:boost::asio completion handler on async_connect never called again after first failureasync_connect 上的 boost::asio 完成处理程序在第一次失败后不再调用
【发布时间】:2019-01-08 15:32:45
【问题描述】:

我正在编写一个使用 boost asio 连接到远程套接字的小型客户端类。如果初始连接失败,它应该能够尝试重新连接。

在测试该场景时,即没有打开的远程套接字,async_connect 的完成处理程序第一次被正确调用。但是当 m_state 再次进入 State_Connect 时,我的完成处理程序将永远不会被再次调用以进行第二次尝试。我做错了什么?

class Test
{
    public:
        Test() : m_socket(m_io)
        {
        }

        void update()
        {
            switch (m_state)
            {
                case State_Connect:
                    std::cout << "Start connect\n";
                    m_socket.async_connect(tcp::endpoint(tcp::v4(), 33000),
                        boost::bind(&Test::onCompleted, this, asio::placeholders::error));
                    m_state = State_Connecting;
                    break;

                case State_Connecting:
                    if (m_error)
                    {
                        m_error.clear();
                        std::cout << "Could not connect\n";
                        m_state = State_Connect;
                    }
                    break;
            }

            m_io.poll_one();
        }

    private:
        void onCompleted(const bs::error_code& error)
        {
            if (error)
            {
                m_error = error;
                m_socket.close();
            }
        }

        enum State
        {
            State_Connect,
            State_Connecting,
        };
        State           m_state = State_Connect;

        asio::io_service    m_io;
        tcp::socket         m_socket;
        bs::error_code      m_error;
};

int main(int argc, char* argv[])
{
    Test test;
    for (;;)
    {
        test.update();
        boost::this_thread::sleep(boost::posix_time::milliseconds(20));
    }
    return 0;
}

输出是: 开始连接 无法连接 开始连接

但我希望它会无限期地重复。

【问题讨论】:

    标签: c++ boost-asio


    【解决方案1】:

    Reference

    当一个 io_context 对象停止时,调用 run()、run_one()、 poll() 或 poll_one() 将立即返回而不调用任何 处理程序。

    当您调用 poll_one() 并且没有准备好处理程序时,poll_one() 函数将 io_service 标记为已停止。当m_stateState_Connecting 时,poll_one() 与此无关,此时 io_service 由于处理程序的空队列而被标记为已停止。

    您可以测试io_service 是否停止,如果停止则调用reset

    if (m_io.stopped())
       m_io.reset();
    m_io.poll_one();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多