简体   繁体   English

Boost异步UDP客户端

[英]Boost Async UDP Client

I've read through the boost:asio documentation (which appears silent on async clients), and looked through here, but can't seem to find the forest for the trees here. 我已经阅读了boost:asio文档(在异步客户端上看起来是沉默的),并在这里浏览了一下,但是似乎在这里找不到树的森林。

I've got a simulation that has a main loop that looks like this: 我有一个模拟,它的主循环如下所示:

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

Easy enough. 很简单。

What I'd like to do, is modify it so that I have: 我想做的就是对其进行修改,以便获得:

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

Where I have the following requirements: 我有以下要求:

  1. I cannot lose data just because I wasn't actively listening. 我不会因为没有积极聆听而丢失数据。 IE I don't want to lose packets because I was in do_stuff2() instead of check_for_new_received_udp_data() at the time the server sent the packet. IE,我不想丢失数据包,因为我在服务器发送数据包时位于do_stuff2()而不是check_for_new_received_udp_data()中。
  2. I can't have check_for_new_received_udp_data() block for more than about 2ms, since the main for loop needs to execute at 60Hz. 我的check_for_new_received_udp_data()块不能超过2ms,因为main for循环需要以60Hz的频率执行。
  3. The server will be running elsewhere, and has a completely erratic schedule. 该服务器将在其他地方运行,并且时间表完全不稳定。 Sometimes there will be no data, othertimes I may get the same packet repeatedly. 有时将没有数据,有时我可能会反复得到相同的数据包。

I've played with the async UDP, but that requires calling io_service.run(), which blocks indefinitely, so that doesn't really help me. 我玩过异步UDP,但这需要调用io_service.run(),它会无限期地阻塞,因此这对我没有帮助。

I thought about timing out a blocking socket read, but it seems you have to cheat and get out of the boost calls to do that, so that's a non-starter. 我曾想过要使阻塞套接字读取超时,但是看来您必须作弊并退出boost调用才能做到这一点,所以这是一个不起眼的事情。

Is the answer going to involve threading? 答案将涉及线程吗? Either way, could someone kindly point me to an example that is somewhat similar? 不管哪种方式,有人可以请我指出一个类似的例子吗? Surely this has been done before. 当然这已经完成了。

To avoid blocking in the io_service::run() you can use io_service::poll_one() . 为了避免阻塞io_service::run() ,可以使用io_service :: poll_one()

Regarding loosing UDP packets, I think you are out of luck. 关于丢失UDP数据包,我认为您很不走运。 UDP does not guarantee delivery, and any part of the network may decide to drop UDP packets if there is much traffic. UDP不能保证传递,如果流量很大,网络的任何部分都可以决定丢弃UDP数据包。 If you need to ensure delivery you need to have either implement some sort of flow control or just use TCP. 如果需要确保交付,则需要实现某种流控制或仅使用TCP。

I think your problem is that you're still thinking synchronously. 我认为您的问题是您仍在同步思考。 You need to think asynchronously. 您需要异步思考。

  1. Async read on UDP socket - will call handler when data arrives. 在UDP套接字上异步读取-数据到达时将调用处理程序。
  2. Within that handler do your processing on the incoming data. 在该处理程序中,对传入数据进行处理。 Keep in mind that while you're processing, if you have a single thread, nothing else dispatches. 请记住,在处理时,如果只有一个线程,则不会分派其他任何线程。 This can be perfectly OK (UDP messages will still be queued in the network stack...). 这可以完全确定(UDP消息仍将在网络堆栈中排队...)。
  3. As a result of this you could be starting other asynchronous operations. 结果,您可能正在启动其他异步操作。

If you need to do work in parallel that is essentially unrelated or offline that will involve threads. 如果您需要并行进行工作,那么这些工作基本上是无关的或脱机的,这将涉及线程。 Create a thread that calls io_service.run(). 创建一个调用io_service.run()的线程。

If you need to do periodic work in an asynch framework use timers . 如果需要在异步框架中进行定期工作,请使用计时器

In your particular example we can rearrange things like this ( psuedo-code ): 在您的特定示例中,我们可以重新排列以下内容( psuedo-code ):

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();
}

Now I'm sure there are other requirements that aren't evident from your question but you'll need to figure out an asynchronous answer to them, this is just an idea. 现在,我确定您的问题中还没有其他要求,但是您需要找出它们的异步答案,这只是一个主意。 Also ask yourself if you really need an asynchronous framework or just use the synchronous socket APIs. 还问自己,您是否真的需要异步框架还是仅使用同步套接字API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM