udp丢包和恢复
Posted
技术标签:
【中文标题】udp丢包和恢复【英文标题】:udp packet loss and recovery 【发布时间】:2011-08-08 11:53:20 【问题描述】:我正在开发基于 udp/tcp 的 P2P 文件和实时视频流应用程序。该应用程序将使用 c++ 为 Linux 和 Windows 平台开发。
我们正在使用 ICE(TCP/UDP 打孔)来实现 P2P。 虽然 TCP 确保数据包丢失,但对于 UDP,我需要一种体面的方法来确保必须将数据包传递给其他对等方。
-
我想知道执行此操作的算法或技术。
是否有任何免费的第三方工具/库可供使用。
任何链接和建议将不胜感激?
【问题讨论】:
【参考方案1】:您需要涵盖 4 个主要问题:
-
数据切片 - UDP 数据报不能包含无限量的信息。因此,您将(经常)需要将您的信息分割成多个数据报,并在另一端重新连接拼图。对于给定的“切片”,您需要唯一的标识符和拼图编号。
从未到达 - UDP 数据报有时会在网络上丢失。如果目标对等方没有收到预期的数据报,则应该有一种机制让他再次请求它。另一种方法是在接收时发送确认。
重播 - 有时,您可能会收到两次相同的 UDP 数据报(原因很复杂)。目标对等方应检测到这一点。
乱序 - 发送的顺序并不总是接收的顺序。目标对等方需要处理这种情况。
您可以实现一个名为slicing window 的协议。我认为您不会为此找到第 3 方库(尽管有人可能在这里证明我错了),因为上述所有内容通常都是由 TCP 本身实现的。
【讨论】:
【参考方案2】:您可能会发现此问题的答案很有帮助:What do you use when you need reliable UDP?
【讨论】:
【参考方案3】:一个简单的方法是为每个数据包设置一个监控线程 --
public void run()
int transmissions = 0;
do
sendPacket();
try
Thread.sleep(1000);
catch (InterruptedException e)
while (!acknowledged() && ++transmissions < MAX_TRANSMISSIONS);
如果性能很重要,可以使用单个线程来监控消息队列。
【讨论】:
这似乎是确保 UDP 数据传输的一种非常不可能的方法,仅此而已...... 为什么说不太可能? 这个简单的解决方案浪费了线程。一个线程这样做仍然是浪费。反应式系统会更好。例如,如果接收方检测到数据包丢失,它可以请求重新发送丢失的数据包。在这种情况下,发送方将收到所述请求,注意到它是对特定数据包的重传请求,并将其排队等待通过 UDP 重新发送。没有线程会只是循环等待某事发生。 @czifro 请求重新传输有时会更好,但这取决于数据包丢失率和消息频率(这会影响接收器检测丢失数据包的速度)。让发送者超时并重新传输通常更有效,因此 TCP 的设计。 @DanielLubarov ,如果您查看 fasp、rbudp 和 QUIC 协议,它们执行的步骤与我概述的非常相似,并且非常可靠且非常快速(它们的执行速度大大超过 TCP)。如您的解决方案中所述,为每个数据包专用一个线程是对资源的巨大浪费。在没有数据包发送的最坏情况下,发送方将被数百个线程阻塞,直到transmissions < MAX_TRANSMISSIONS == false
。以上是关于udp丢包和恢复的主要内容,如果未能解决你的问题,请参考以下文章