我要求以每秒1000个数据包的固定速率接收UDP数据包流。它们由28个字节的有效载荷组成,其中前四个字节(Uint32)是分组序列号。发送方是同一本地网络中的嵌入式设备,地址和端口是相互已知的。我不希望收到每个数据包,但主机的设计应使其不会增加内在的UDP协议限制。
我以前只有有限的UDP和套接字经验(只需从Android手机上的传感器应用程序到PC,然后进行小型演示项目)。
我不确定以最快的速度接收所有数据包的最明智的方法是什么。我想象某种循环,或者某种自我重新触发的接收操作。我研究了同步和异步接收之间的区别,以及基于任务的异步模式(TAP),但我还没有感到非常自信。它看起来像一个简单的任务,但它的理解对我来说仍然很复杂。
所以问题是:
UdpClient
类是否适合这样的场景,或者我最好使用Socket
类? (或者另一个,顺便说一下)我应该使用同步还是异步接收?如果我使用同步,我害怕丢失数据包,如果我使用异步,我应该如何计时/限制接收操作,以便我不会以太大的速率启动它们?
- 醇>
我想到了
UdpClient.Available()
的紧密循环测试,如下所示。它会是一个很好的设计选择吗?
while (running)
{
if (udpSocket.Available() > 0)
{
// do something (what?)
}
}
答案 0 :(得分:1)
使用UdpClient.Receive()尽可能快地从您的UdpClient中读取(或者尽可能快地为您的应用程序读取)。如果没有传入数据包,Receive()操作将阻塞(等待),因此连续三次调用Receive()将始终返回三个UDP数据包。
通常,在接收UDP数据包时,您不必担心发送速率。只有发件人需要担心发送速率。因此,发送者的相反建议是:不要尽可能快地发送大量UDP数据包。
所以我的答案是:
是的,请使用UdpClient。
使用同步接收。在您的接收线程中运行的循环中调用UdpClient.Receive(),在您的程序的主循环中,您喜欢什么。
您无需检查可用数据。 UdpClient.Receive()将阻塞,直到有可用数据。
收到UDP时不要害怕丢失数据包:你几乎不会丢失接收主机 上的UDP数据包,因为你在接收时做错了。 UDP数据包通常被网络组件(如网络路径上某处的路由器)丢弃,这些组件无法像接收到的那样快速地发送(转发)UDP数据包。
一旦数据包到达您的计算机,您的操作系统会进行相当数量的缓冲(例如Linux上的128k),因此即使您的应用程序没有响应,例如1秒,它也不会丢失任何UDP数据包。