【问题标题】:Setting ASIO timeout for stream为流设置 ASIO 超时
【发布时间】:2014-02-20 14:25:29
【问题描述】:

我正在尝试为我在 boost 中使用 ASIO 创建的套接字设置超时,但没有成功。我在网站的其他地方找到了以下代码:

tcp::socket socket(io_service);
    struct timeval tv;
    tv.tv_sec  = 5;
    tv.tv_usec = 0;
    setsockopt(socket.native(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    setsockopt(socket.native(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
boost::asio::connect(socket, endpoint_iterator);

超时保持在相同的 60 秒,而不是我在连接调用中寻找的 5 秒。我错过了什么?请注意,连接代码在所有其他情况下都可以正常工作(没有超时)。

【问题讨论】:

    标签: c++ boost-asio


    【解决方案1】:

    您设置的套接字选项不适用于connect AFAIK。 这可以通过使用异步 asio API 来完成,如下面的 asio example

    有趣的部分是设置超时处理程序:

    deadline_.async_wait(boost::bind(&client::check_deadline, this));
    

    启动计时器

    void start_connect(tcp::resolver::iterator endpoint_iter)
    {
      if (endpoint_iter != tcp::resolver::iterator())
      {
        std::cout << "Trying " << endpoint_iter->endpoint() << "...\n";
    
        // Set a deadline for the connect operation.
        deadline_.expires_from_now(boost::posix_time::seconds(60));
    
        // Start the asynchronous connect operation.
        socket_.async_connect(endpoint_iter->endpoint(),
            boost::bind(&client::handle_connect,
            this, _1, endpoint_iter));
      }
      else
      {
        // There are no more endpoints to try. Shut down the client.
        stop();
      }
    }
    

    并关闭应该导致连接完成处理程序运行的套接字。

    void check_deadline()
    {
      if (stopped_)
        return;
    
      // Check whether the deadline has passed. We compare the deadline against
      // the current time since a new asynchronous operation may have moved the
      // deadline before this actor had a chance to run.
      if (deadline_.expires_at() <= deadline_timer::traits_type::now())
      {
        // The deadline has passed. The socket is closed so that any outstanding
        // asynchronous operations are cancelled.
        socket_.close();
    
        // There is no longer an active deadline. The expiry is set to positive
        // infinity so that the actor takes no action until a new deadline is set.
        deadline_.expires_at(boost::posix_time::pos_infin);
      }
    
      // Put the actor back to sleep.
      deadline_.async_wait(boost::bind(&client::check_deadline, this));
    }
    

    【讨论】:

    • 谢谢。我只是发现它们不适用于连接。我打算拼凑一个计时器来执行我自己的 SIG 处理。我更喜欢你的方式。
    • 好吧,太好了 :) 这不是我的方式,它来自 asio 的作者 Chris Kohlhoff 的示例。
    • 这是一个很好的解决方案 Ralf,我通常会使用现有的 asio::io_service 作为计时器来处理我的超时。我要添加的唯一额外功能是您可以绑定回调以在超时时执行。如果你的系统想要/需要一个超时通知来执行一些清理、重试或其他类似的事情而不停止套接字,那么你可以将代码放在定时器到期回调中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 2010-09-27
    • 2017-07-31
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 2010-12-21
    相关资源
    最近更新 更多