我写了一个C ++应用程序(在Linux上运行),它提供大约400 kbps的RTP流。对于大多数目的地,这工作正常,但一些目的地经验包丢失。有问题的目的地似乎有一个较慢的连接,但它应该足够快到我正在发送的流。
由于这些目的地能够在没有数据包丢失的情况下为其他应用程序接收类似的RTP流,因此我的应用程序可能有问题。
我已经验证了一些事情: - 在tcpdump中,我看到所有RTP数据包都在发送机器上传出 - 有一个UDP发送缓冲区(我试过64KB到300KB之间的大小) - RTP数据包大多数保持在1400字节以下,以避免碎片
发送应用程序可以做些什么来最小化丢包的可能性以及调试这种情况的最佳方法是什么?
答案 0 :(得分:9)
不要以大块突发的方式发送数据包。
数据包丢失通常是由数据包缓冲区大小有限的慢速路由器引起的。慢速路由器可能能够处理1 Mbps就好了如果它有时间发送出10个数据包然后再接收10个数据包,但如果100 Mbps发送方向它发送了大量50个数据包它就别无选择但只能掉线其中40个。
尝试展开发送,以便您只在每个时间段内写下必要的内容。如果你必须每五分钟写一个数据包,那就这样做,而不是每秒写5个数据包。
答案 1 :(得分:5)
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每一跳。 这可能会检测到您路线中的慢跳。在其他机器上运行它以检查与第二台机器的连接。
答案 2 :(得分:4)
RTP通常使用UDP,这本质上是有损的。发送者和接收者之间的任何地方都可能丢失数据包,因此本地调试不会显示任何有用的内容。
明显的事情要做:
如果一切都失败了,WireShark就是你的朋友。它将为您提供有关数据量的真实情况 - 以及您的应用程序何时发送数据。
答案 3 :(得分:1)
您应该尝试降低发送数据包的速率。缓慢的连接可能意味着各种各样的事情,并试图以高速率发送数据包(小或大)无济于事。
答案 4 :(得分:-2)
这可能不是您想要的答案,但如果我遇到丢包问题,我会尝试将我的应用程序切换为使用TCP,并且最让我担心数据包丢失的问题。