【问题标题】:udp packet loss and recoveryudp丢包和恢复
【发布时间】:2011-08-08 11:53:20
【问题描述】:

我正在开发基于 udp/tcp 的 P2P 文件和实时视频流应用程序。该应用程序将使用 c++ 为 Linux 和 Windows 平台开发。

我们正在使用 ICE(TCP/UDP 打孔)来实现 P2P。 虽然 TCP 确保数据包丢失,但对于 UDP,我需要一种体面的方法来确保必须将数据包传递给其他对等方。

  1. 我想知道执行此操作的算法或技术。
  2. 是否有任何免费的第三方工具/库可供使用。

任何链接和建议将不胜感激?

【问题讨论】:

    标签: network-programming udp p2p hole-punching


    【解决方案1】:

    您需要涵盖 4 个主要问题:

    1. 数据切片 - UDP 数据报不能包含无限量的信息。因此,您将(经常)需要将您的信息分割成多个数据报,并在另一端重新连接拼图。对于给定的“切片”,您需要唯一的标识符和拼图编号。
    2. 从未到达 - UDP 数据报有时会在网络上丢失。如果目标对等方没有收到预期的数据报,则应该有一种机制让他再次请求它。另一种方法是在接收时发送确认。
    3. 重播 - 有时,您可能会收到两次相同的 UDP 数据报(原因很复杂)。目标对等方应检测到这一点。
    4. 乱序 - 发送的顺序并不总是接收的顺序。目标对等方需要处理这种情况。

    您可以实现一个名为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 &lt; MAX_TRANSMISSIONS == false
        猜你喜欢
        • 2013-11-21
        • 1970-01-01
        • 2013-08-26
        • 1970-01-01
        • 2021-03-15
        • 2018-03-18
        • 2013-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多