提升Asio,async_read / connect超时

时间:2016-07-31 09:55:45

标签: c++ boost timeout boost-asio

在boost网站中,关于异步操作的超时有一个很好的example。但是,在该示例中,套接字关闭以取消操作。还有socket :: cancel(),但是在文档和编译器警告中,它都表示在可移植性方面存在问题。

在SO中的Boost.Asio超时问题堆栈中,有几种答案。第一个可能是引入自定义事件循环,即循环io_service :: run_one()并在截止日期取消事件循环。我在工作线程中使用io_service :: run()。如果可能的话,这不是我想要使用的解决方案,因为我不想更改我的代码库。

第二个选项是直接更改本机套接字的选项。但是,如果可能的话,我想坚持使用Boost.Asio,并尽可能避免任何类型的平台特定代码。

文档中的示例是旧版本的Boost.Asio,但它正常工作,而不是被迫关闭套接字以取消操作。使用文档示例,我有以下

void check_deadline(const boost::system::error_code &ec)
{
    if(!running) {
       return;
    }

    if(timer.expires_at() <= boost::asio::deadline_timer::traits_type::now()) {

        // cancel all operations
        boost::system::error_code errorcode;
        boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
        socket.close(errorcode);
        if(errorcode) {
            SLOGERROR(mutex, errorcode.message(), "check_deadline()");
        }
        else {
            SLOG(mutex, "timed out", "check_deadline()");

            // connect again
            Connect(endpoint);
            if(errorcode) {
                SLOGERROR(mutex, errorcode.message(), "check_deadline()");
            }
        }

        // set timer to infinity, so that it won't expire
        // until a proper deadline is set
        timer.expires_at(boost::posix_time::pos_infin);
    }

    // keep waiting
    timer.async_wait(std::bind(&TCPClient::check_deadline, this, std::placeholders::_1));
}

这是注册到async_wait的唯一回调函数。我可以提出的第一个解决方案是在关闭套接字后重新连接。现在我的问题是,有更好的方法吗?通过更好的方式,我的意思是取消基于计时器的操作,而不会实际中断(即,不关闭套接字)连接。

0 个答案:

没有答案