7

我编写了一个 C++ 应用程序(在 Linux 上运行),它提供大约 400 kbps 的 RTP 流。对于大多数目的地来说,这可以正常工作,但有些目的地会出现数据包丢失。有问题的目的地似乎有一个共同的较慢的连接,但对于我发送的流来说它应该足够快。

由于这些目的地能够为其他应用程序接收类似的 RTP 流而不会丢失数据包,因此我的应用程序可能有问题。

我已经验证了一些事情: - 在 tcpdump 中,我看到所有 RTP 数据包都在发送机器上发出 - 有一个 UDP 发送缓冲区(我尝试了 64KB 和 300KB 之间的大小) - RTP 数据包大多保持在 1400 字节以下避免碎片化

发送应用程序可以做些什么来最大程度地减少数据包丢失的可能性,以及调试这种情况的最佳方法是什么?

4

5 回答 5

9

不要以大块的突发块发送数据包。

数据包丢失通常是由具有有限数据包缓冲区大小的慢速路由器引起的。如果慢速路由器有时间发送 10 个数据包,然后再接收 10 个数据包,它可能能够处理 1 Mbps,但如果 100 Mbps 发送方向它发送一大块 50 个数据包,它别无选择,只能丢弃其中40个。

尝试分散发送,以便您只写每个时间段内必须写的内容。如果您必须每五分之一秒写入一个数据包,请这样做,而不是每秒写入 5 个数据包。

于 2010-04-27T18:46:40.123 回答
6

netstat 有几个有用的选项来调试情况。

第一个是 netstat -su(转储 UDP 统计信息):

dima@linux-z8mw:/media> netstat -su                                                      
IcmpMsg:                                                                                 
    InType3: 679
    InType4: 20
    InType11: 548
    OutType3: 100
Udp:
    12945 packets received
    88 packets to unknown port received.
    0 packet receive errors
    13139 packets sent
    RcvbufErrors: 0
    SndbufErrors: 0
UdpLite:
    InDatagrams: 0
    NoPorts: 0
    InErrors: 0
    OutDatagrams: 0
    RcvbufErrors: 0
    SndbufErrors: 0
IpExt:
    InNoRoutes: 0
    InTruncatedPkts: 0
    InMcastPkts: 3877
    OutMcastPkts: 3881
    InBcastPkts: 0
    OutBcastPkts: 0
    InOctets: 7172779304
    OutOctets: 785498393
    InMcastOctets: 525749
    OutMcastOctets: 525909
    InBcastOctets: 0
    OutBcastOctets: 0

注意“RcvbufErrors”和“SndbufErrors”

附加选项是监视进程的接收和发送 UDP 缓冲区:

dima@linux-z8mw:/media> netstat -ua
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
udp        0      0 *:bootpc                *:*
udp        0      0 *:40134                 *:*
udp        0      0 *:737                   *:*
udp        0      0 *:mdns                  *:*

在这里您需要查看您感兴趣的连接的 Recv-Q 和 Send-Q 列。如果值很高并且没有降至零,则该过程无法处理负载。

您可以在发送和接收机器上使用这些命令。

您也可以使用mtr,它结合了 traceroute 和 ping - 它 ping 路由中的每个跃点。这可能会检测到您的路由中的慢跳。在其他机器上运行它以检查与第二台机器的连接。

于 2010-04-27T18:46:05.187 回答
4

RTP通常使用UDP,它本质上是有损的。数据包可能会在发送方和接收方之间的任何地方丢失,因此本地调试不会显示任何有用的信息。

明显要做的事情:

  • a:降低整体数据速率
  • b:通过更频繁地发送小数据包而不是每隔几秒发送一个大数据块来降低“峰值”数据速率。即,减少您的 UDP 发送缓冲区 - 甚至可能只有 1400 个字节。
  • c: 看看是否可以切换到 RTP 的 TCP 变体。

如果一切都失败了,WireShark是你的朋友。它将让您真实地了解您的应用程序发送了多少数据以及何时发送。

于 2010-04-27T19:33:14.030 回答
0

您应该尝试降低发送数据包的速率。缓慢的连接可能意味着各种各样的事情,尝试以高速率发送数据包(无论大小)都无济于事。

于 2010-04-27T18:11:18.467 回答
-3

这可能不是您想要的答案,但如果我遇到丢包问题,我会尝试将我的应用程序切换为使用 TCP,并且让我不再担心丢包。

于 2010-04-27T18:02:30.587 回答