Boost Asio UDP检索套接字缓冲区中的最后一个数据包 [英] Boost Asio UDP retrieve last packet in socket buffer

查看:71
本文介绍了Boost Asio UDP检索套接字缓冲区中的最后一个数据包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天来,我一直在搞乱 Boost Asio ,但是我被这种奇怪的行为所困扰.请让我解释一下.

I have been messing around Boost Asio for some days now but I got stuck with this weird behavior. Please let me explain.

计算机A每500毫秒向计算机B发送一个连续的udp数据包,计算机B希望以自己的速度读取A的数据包,但只希望A的最后一个数据包,显然是最新的数据包.

Computer A is sending continuos udp packets every 500 ms to computer B, computer B desires to read A's packets with it own velocity but only wants A's last packet, obviously the most updated one.

我已经注意到,当我执行以下操作时:

It has come to my attention that when I do a:

mSocket.receive_from(boost :: asio :: buffer(mBuffer),mEndPoint);

我可以获得几乎未处理的OLD数据包.

I can get OLD packets that were not processed (almost everytime).

这有意义吗?我的一个朋友告诉我,套接字维护数据包的缓冲区,因此,如果我读取的频率比发送方的频率低,则可能会发生这种情况.

Does this make any sense? A friend of mine told me that sockets maintain a buffer of packets and therefore If I read with a lower frequency than the sender this could happen. ¡?

所以,第一个问题是如何接收最后一个数据包并丢弃我错过的数据包?

So, the first question is how is it possible to receive the last packet and discard the ones I missed?

稍后,我尝试使用Boost文档的异步示例,但发现它没有达到我想要的效果.

Later I tried using the async example of the Boost documentation but found it did not do what I wanted.

http://www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/tutorial/tutdaytime6.html

据我所知, async_receive_from 应在数据包到达时调用方法"handle_receive" ,该方法适用于服务后的第一个数据包运行" .

From what I could tell the async_receive_from should call the method "handle_receive" when a packet arrives, and that works for the first packet after the service was "run".

如果我想继续监听端口,则应在句柄代码中再次调用 async_receive_from .对吧?

If I wanted to keep listening the port I should call the async_receive_from again in the handle code. right?

但是我发现我开始了一个无限循环,它不会等到下一个数据包,而只是一次又一次地输入"handle_receive" .

BUT what I found is that I start an infinite loop, it doesn't wait till the next packet, it just enters "handle_receive" again and again.

我没有在做服务器应用程序,正在发生很多事情(它是一个游戏),所以我的第二个问题是,我是否必须使用线程来正确地使用异步接收方法,是否有一些示例线程和异步接收?

I'm not doing a server application, a lot of things are going on (its a game), so my second question is, do I have to use threads to use the async receive method properly, is there some example with threads and async receive?

推荐答案

在Windows(某些情况下为XP,Vista和7)上;如果将recv缓冲区的大小设置为零,则只有在数据报到达时有未决的recv时,才会接收数据报.这可以做您想要的,但是如果您在最后一个数据报到达后发布Recv,则必须坐下来等待下一个……

With Windows (certainly XP, Vista, & 7); if you set your recv buffer size to zero you'll only receive datagrams if you have a recv pending when the datagram arrives. This MAY do what you want but you'll have to sit and wait for the next one if you post your recv just after the last datagram arrives ...

由于您正在玩游戏,恕我直言,使用UDP构建的内容要比UDP本身好得多.看看 ENet 支持基于UDP的可靠数据,还支持基于UDP的不可靠的排序"数据.对于不可靠的排序数据,您只能获得最新"数据.或者像 RakNet 之类的东西可能对您有用,因为它可以做很多游戏,并且还包括类似于ENet排序数据的内容.

Since you're doing a game, it would be far better, IMHO, is to use something built on UDP rather than UDP itself. Take a look at ENet which supports reliable data over UDP and also unreliable 'sequenced' data over UDP. With unreliable sequenced data you only ever get the 'latest' data. Or something like RakNet might be useful to you as it does a lot of games stuff and also includes stuff similar to ENet's sequenced data.

您应该记住的另一件事是,使用原始UDP可能会使这些数据报乱序,并且可能会多次获取它们.因此,如果您不使用某些可以为您排序数据的内容,那么无论如何您都将需要自己的序列号.

Something else you should bear in mind is that with raw UDP you may get those datagrams out of order and you may get them more than once. So you're likely gonna need your own sequence number in their anyway if you don't use something which sequences the data for you.

这篇关于Boost Asio UDP检索套接字缓冲区中的最后一个数据包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆