为流设置ASIO超时

时间:2014-02-20 14:25:29

标签: c++ boost-asio

我正在尝试设置一个套接字的超时,我已经使用ASIO在boost中创建了没有运气的套接字。我在网站的其他地方找到了以下代码:

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秒。我错过了什么?请注意,连接代码在所有其他情况下(没有超时)都可以正常工作。

1 个答案:

答案 0 :(得分: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));
}