【问题标题】:Can Linux buffer UDP packets to correct the sequenceLinux 可以缓冲 UDP 数据包来纠正顺序吗
【发布时间】:2021-07-02 08:16:50
【问题描述】:

美好的一天,

我正在使用 UDP 通过 Internet 传输 MP3 音频。是的,由于各种原因,这很可能是一个坏主意,但是我的用例将我限制在此设置中。为了进一步扩展下面的 cmets,我的源设备通过非常高的延迟链路连接,吞吐量低且有限,因为这些设备位于农村/偏远地区。我的延迟时间长达 1 秒(令人震惊的是)。因此,使用 TCP 会降低我的服务,因为它有两种方式 coms、acks、resends 等。

我要解决的问题是,在接收服务器(Linux Ubuntu 18.04)上,我看到了所有数据包,但很多时候有点乱序。 IE。数据包 5 在数据包 4 之前。

Linux 中是否有办法缓冲传入的 UDP 流,以便消费者(在我的情况下为 FFMPEG)能够按顺序获取流(作为缓冲区,具有预期的延迟,与缓冲区大小相关联)。

Tcpdump 问题示例(注意:id 乱序):

16:04:48.648448 IP (tos 0x0, ttl 24, id 25335, offset 0, flags [DF], proto UDP (17), length 108)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 80
16:04:48.648503 IP (tos 0x0, ttl 24, id 25334, offset 0, flags [DF], proto UDP (17), length 1228)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 1200
16:04:48.884324 IP (tos 0x0, ttl 24, id 25336, offset 0, flags [DF], proto UDP (17), length 1228)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 1200
16:04:48.884357 IP (tos 0x0, ttl 24, id 25337, offset 0, flags [DF], proto UDP (17), length 108)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 80
16:04:49.145213 IP (tos 0x0, ttl 24, id 25339, offset 0, flags [DF], proto UDP (17), length 108)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 80
16:04:49.145257 IP (tos 0x0, ttl 24, id 25338, offset 0, flags [DF], proto UDP (17), length 1228)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 1200
16:04:49.406068 IP (tos 0x0, ttl 24, id 25340, offset 0, flags [DF], proto UDP (17), length 1228)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 1200
16:04:49.406125 IP (tos 0x0, ttl 24, id 25341, offset 0, flags [DF], proto UDP (17), length 108)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 80
16:04:49.667095 IP (tos 0x0, ttl 24, id 25342, offset 0, flags [DF], proto UDP (17), length 1228)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 1200
16:04:49.667175 IP (tos 0x0, ttl 24, id 25343, offset 0, flags [DF], proto UDP (17), length 108)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 80
16:04:49.929139 IP (tos 0x0, ttl 24, id 25344, offset 0, flags [DF], proto UDP (17), length 1228)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 1200
16:04:49.929200 IP (tos 0x0, ttl 24, id 25345, offset 0, flags [DF], proto UDP (17), length 108)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 80
16:04:50.164307 IP (tos 0x0, ttl 24, id 25346, offset 0, flags [DF], proto UDP (17), length 1228)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 1200
16:04:50.164385 IP (tos 0x0, ttl 24, id 25347, offset 0, flags [DF], proto UDP (17), length 108)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 80
16:04:50.425221 IP (tos 0x0, ttl 24, id 25348, offset 0, flags [DF], proto UDP (17), length 1228)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 1200
16:04:50.425285 IP (tos 0x0, ttl 24, id 25349, offset 0, flags [DF], proto UDP (17), length 108)
    xx.xx.xx.xx.2011 > 172.xx.xx.xx.2011: UDP, length 80

【问题讨论】:

  • 如果你关心流量的顺序,你应该考虑 TCP 而不是 UDP。
  • 由于各种原因,假设我不能在我目前的用例中使用 TCP。
  • 这能回答你的问题吗? Ensuring packet order in UDP
  • @red0ct :-D 这很好。
  • 实施排序后,您可以开始保证交付和拥塞控制。

标签: linux networking ffmpeg linux-kernel udp


【解决方案1】:

UDP 协议不关心顺序问题以及保证交付。
所以Linux UDP实现即使在理论上也不能保证在接收端遵守传输数据包的顺序(而网络中的一些数据包可以遵循不同的方式导致接收端洗牌)。这只是协议问题,与 TCP 相比,UDP 协议没有任何资源来实现这一点。

顺便说一句,您可以实现一些 L7(应用程序级别)逻辑来处理序列问题。但这是通过 UDP 传输媒体流量(VoIP - 例如 SIP-over-TCP/UDP + RTP-over-UDP 等)的常见情况,因为在媒体传输(语音、视频,...)。

另请阅读:Ensuring packet order in UDP

【讨论】:

    猜你喜欢
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多