【问题标题】:boost::asio how to implement a timed packet send feature?boost::asio 如何实现定时数据包发送功能?
【发布时间】:2012-12-27 20:32:54
【问题描述】:

我有一个服务器应用程序,它使用 boost::asio 的异步读/写函数与正在连接的客户端进行通信(直到它们断开连接)。

到目前为止一切都很好,但我想实现某种定时方法,服务器在经过一定时间后自行发送数据包。

我主要遵循boost::asio website 上的教程/示例,所以我的程序基本上与给定示例具有相同的结构。

我尝试通过创建一个 asio::deadline 计时器对象并将其传递给我已经通过调用 io_service.run() 来“调用”的 io_service 对象来实现此功能,如下所示:

asio::deadline_timer t(*io, posix_time::seconds(200));
t.async_wait(boost::bind(&connection::handle_timed, 
                this, boost::asio::placeholders::error));

handle_timed 处理程序如下所示:

void connection::handle_timed(const system::error_code& error)
{
    //Ping packet is created here and gets stored in send_data

    async_write(socket_, asio::buffer(send_data, send_length), 
                boost::bind(&connection::handle_write, this, boost::asio::placeholders::error));
}

但是我遇到的问题是,deadline_timer 没有等待给定的时间,他几乎立即进入处理函数并想要发送数据包。

就像他一接触到异步操作就处理它,那肯定不是我想要的。

难道我不能在使用 io_service.run() 调用 io_service 对象后添加新的“对象”吗?或者我之后可能必须将它专门包含在 io_service 对象的工作队列中?

我也很难理解如何在不与正常的消息流量混淆的情况下实现这一点。

【问题讨论】:

  • 你在使用 TCP 套接字吗?如果是这样,你可以考虑keep alive
  • 是的,我正在使用 TCP 套接字,但我更愿意将数据包与我通常发送的其他数据包一起发送,因为我想在其中放入一些数据。

标签: c++ windows networking timer boost-asio


【解决方案1】:

您可以随时向io_service 添加工作。您应该检查 async_wait() 回调中的错误,在我看来,您的 deadline_timer 超出范围

asio::deadline_timer t(*io, posix_time::seconds(200));
t.async_wait(boost::bind(&connection::handle_timed, 
                this, boost::asio::placeholders::error));
...
// t goes out of scope here

你应该让它成为你的 connection 类的成员,就像 socket_ 一样。或者,使用 boost::enable_shared_from_this 并在完成处理程序中保留一份副本:

const boost::shared_ptr<asio::deadline_timer> t(new asio::deadline_timer(*io, posix_time::seconds(200)));
t.async_wait(boost::bind(&connection::handle_timed, 
                this, boost::asio::placeholders, t));

和你的完成处理程序

void connection::handle_timed(
    const system::error_code& error,
    const boost::shared_ptr<asio::deadline_timer>& timer
    )
{
    //Ping packet is created here and gets stored in send_data

    async_write(socket_, asio::buffer(send_data, send_length), 
                boost::bind(&connection::handle_write, this, boost::asio::placeholders::error));
}

【讨论】:

  • 感谢您的快速回答,将deadline_timer 对象添加到类中就可以了。
  • @user 没问题,祝你好运。如果您遇到困难,请提出其他问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 1970-01-01
相关资源
最近更新 更多