【问题标题】:Boost.ASIO UDP socket: sink all the packetsBoost.ASIO UDP 套接字:接收所有数据包
【发布时间】:2015-11-28 12:15:23
【问题描述】:

我正在使用 boost::asio::ip::udp::socket 通过 socket 的 async_receive_from 方法接收 UDP 数据包。

代码运行良好,唯一的问题是在我处理一个数据包时,会创建一个队列(缓冲区)来处理更多。但我的程序必须接收自处理开始以来收到的所有数据包,以便它只侦听最近的数据包。

例子:

  • 数据包 1 已发送
  • 数据包 1 正在处理中
  • 数据包 2、3、4 已发送
  • 数据包 1 结束计算
  • 刷新缓冲区
  • 数据包 5 已发送
  • 数据包 5 正在处理中

有什么方法可以丢弃中间的数据包吗? 谢谢!

【问题讨论】:

  • 您必须在处理数据包之前存储和订购数据包。例如,您可以将它们添加到列表中,然后从后面处理此列表。
  • 感谢 user743414。我目前是通过缓冲区来做的。我不想处理“旧”数据包,我只想处理尽可能多的数据包,丢弃中间的数据包。
  • 定义“旧”数据包?您使用的是时间戳还是简单的向上计数 id?当您只想处理最后一个数据包时,您只需存储最后收到的数据包。
  • 不,没什么,它们只是覆盖自己的命令。我只需要处理最后一个,否则我会造成延迟。我不需要在中间处理数据包。而且我无法指定缓冲区的最小大小,因为数据包的大小不同
  • 数据包1的处理是在发送端还是在接收端?

标签: c++ boost udp buffer boost-asio


【解决方案1】:
  1. 使用只保存一个数据报的缓冲区。

  2. 继续读取缓冲区,直到没有更多数据报可供读取。

  3. 如果您读取了至少一个数据包,则处理缓冲区中的数据报。

  4. 转到第 2 步。

请注意,UDP 是数据报协议,而不是数据包协议。单个 UDP 数据报可以拆分为多个数据包。

【讨论】:

  • 谢谢大卫。不幸的是,数据报的大小因命令而异,因此我无法制作大小定制的缓冲区。我可能会做的是异步侦听UDP数据报,解析接收到的字节(缓冲区足够大以获取更重的数据报)并最终同步接收,非阻塞,直到我没有字节可以读取......这行吗?
  • @Jack 不要为只存在很短时间的东西制作大小定制的缓冲区。只需使用固定大小的缓冲区。如果以后发生需要将对象保留更长时间的情况,请将其复制到大小合适的缓冲区中。
  • 你好大卫。我想我误解了您的第一点:“使用仅包含单个数据报的缓冲区”-您的意思是什么?
  • @Jack 我的意思是一个缓冲区保存一个数据报。
  • 我已经解决了混合异步/同步的问题:在收到第一条异步消息时,处理它并读取平均接收到的任何数据,同时将套接字设置为非阻塞,同步读取数据直到缓冲区包含数据,然后将套接字设置回阻塞并再次调用异步侦听方法。
【解决方案2】:

我觉得可以很简单:

  1. async_receive_from 直到收到数据包。
  2. 检查available方法确定套接字中有更多数据。
  3. 如果我们有更多数据,丢弃缓冲区并转到 1;否则处理数据包

【讨论】:

  • 您好 PSIAlt,感谢您的回答。我看到了可用的方法,我正在考虑丢弃缓冲区,但我无法做到。你是如何丢弃缓冲区的?
  • @Jack 不可能,sockets API 没有这个功能。你只能读取数据,什么都不做。
猜你喜欢
  • 2015-11-26
  • 2013-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-18
  • 2010-11-13
  • 2014-10-12
  • 2012-12-29
相关资源
最近更新 更多