增强异步UDP客户端

时间:2013-03-24 20:22:23

标签: sockets boost asynchronous udp boost-asio

我已经阅读了boost:asio文档(在异步客户端上显示无声),并在这里查看,但似乎无法在这里找到树林。

我的模拟主循环看起来像这样:

for(;;)
{
  a = do_stuff1();
  do_stuff2(a);
}

很容易。

我想做的是修改它以便我有:

for(;;)
{
  a = do_stuff1();
  check_for_new_received_udp_data(&b);
  modify_a_with_data_from_b(a,b);
  do_stuff2(a);
}

我有以下要求:

  1. 我不能因为我没有积极倾听而丢失数据。 IE我不想丢失数据包,因为在服务器发送数据包时我在do_stuff2()而不是check_for_new_received_udp_data()。
  2. 我不能让check_for_new_received_udp_data()块超过大约2ms,因为主for循环需要以60Hz执行。
  3. 服务器将在其他地方运行,并且计划完全不稳定。有时候没有数据,其他我可能会重复获得相同的数据包。
  4. 我玩过异步UDP,但这需要调用无限期阻塞的io_service.run(),这对我没有帮助。

    我考虑过暂停一个阻塞套接字读取,但似乎你必须作弊并退出激活调用才能做到这一点,所以这是一个非首发。

    答案是否涉及线程?无论哪种方式,有人可以指出一个有点相似的例子吗?当然这已经完成了。

2 个答案:

答案 0 :(得分:3)

为避免在io_service::run()中阻止,您可以使用io_service::poll_one()

关于丢失UDP数据包,我认为你运气不好。 UDP不保证传送,如果流量很大,网络的任何部分都可能决定丢弃UDP数据包。如果您需要确保交付,您需要实现某种流量控制或只使用TCP。

答案 1 :(得分:3)

我认为你的问题是你还在同步思考。你需要异步思考。

  1. UDP套接字上的异步读取 - 将在数据到达时调用处理程序。
  2. 在该处理程序中对传入数据进行处理。请记住,在您处理时,如果您有一个单独的线程,则不会发送任何其他内容。这可以完全正常(UDP消息仍将在网络堆栈中排队......)。
  3. 因此,您可以启动其他异步操作。
  4. 如果您需要并行工作,这些工作基本上不相关或脱机,涉及线程。创建一个调用io_service.run()的线程。

    如果您需要在异步框架中定期工作,请使用timers

    在您的特定示例中,我们可以重新排列此类内容(伪代码):

    read_handler( ... )
    {
       modify_a_with_data_from_b(a,b);
       do_stuff2(a);
       a = do_stuff1();
       udp->async_read( ..., read_handler );
    }
    
    periodic_handler(...)
    {
      // do periodic stuff
      timer.async_wait( ..., periodic_handler );
    }
    
    main()
    {
       ...
       a = do_stuff1();
       udp->async_read( ..., read_handler )
       timer.async_wait( ..., periodic_handler );
    
       io_service.run();
    }
    

    现在我确定你的问题中还有其他一些要求并不明显,但你需要弄清楚它们的异步答案,这只是一个想法。还要问问自己是否真的需要异步框架或只使用同步套接字API。