2010-04-27 56 views
5

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

因为这些目的地都能够收到类似RTP为无丢包其他应用程序流,我的应用程序可能会出现故障。

我已经验证的几件事情: - 在tcpdump的,我看到所有的RTP包走出去送机 上 - 有一个UDP的地方(我试过64KB和300KB之间大小) 发送缓冲区 - 该RTP包大多停留低于1400个字节,以避免碎片

什么可以发送应用程序做,以尽量减少数据包丢失的可能性,这将是调试这种情况最好的方法是什么?

回答

9

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

分组丢失通常是由具有有限包缓冲区的大小缓慢路由器引起的。缓慢的路由器可能能够处理1 Mbps的就好了,如果有时间接收到另一条10日前发出比如说,10个包,但如果100 Mbps的发送方将其发送50个数据包的一大块就别无选择,只能放弃其中40人。

尝试铺开发送,让你只写了什么是必要的,每个时间段来写。如果您必须每五秒钟写一个数据包,请按照这种方式进行,而不是每秒写入5个数据包。

-2

这可能不是你想要的答案,但如果我有丢包的问题我想尝试改用我的应用程序使用TCP,并且已经采取了我的脑海丢包的大部分忧虑。

+0

RTP的很大一点是利用UDP语义;特别是允许丢失数据包而不会拖延流的其余部分。 – jesup 2010-05-13 08:15:29

+0

糟糕!我对RTP无知是个不好的因素。我现在就去阅读。感谢您的领导! – 2010-05-13 09:00:43

1

您应该尝试降低发送数据包的速率。慢速连接可能意味着各种各样的事情,并试图以高速率发送数据包(小或大)不会有帮助。

5

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

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

[email protected]:/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缓冲区:

[email protected]:/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列。如果数值较高并且不降为零,则比进程无法处理负载。

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

您也可以使用地铁,它结合了跟踪路由和ping - 要乒每一跳的路由。 这可能会检测到您的路线中的慢速跳跃。在其他机器上运行它以检查与第二个机器的连接。

+1

这里有一些很好的建议,但我不确定这会对他有帮助。实际的数据包丢失可能发生在ISP路由器上,他无法查看统计信息。 – 2010-04-27 18:50:46

+0

事实上,我发现在发送机器上没有任何数据包丢失与netstat。不幸的是,到目的地的路径涉及很多我无法直接访问的网络设备。 – 2010-04-27 19:02:37

+0

在这种情况下,netstat不可能显示任何有用的东西。 – Roddy 2010-04-27 19:34:27

4

RTP通常使用UDP,这本质上是有损的。数据包可能在发送者和接收者之间的任何地方丢失,所以本地调试将告诉你什么都没有用。

明显的事情要做:

  • 一个:降低整体数据速率
  • B:减少“峰值”的数据速率,通过 发送小数据包往往 而不是一个大块每隔几 秒。即减少你的UDP发送缓冲区 - 也许只有1400 字节。
  • c:看看您是否可以切换到RTP的TCP 变种。

如果一切都失败,WireShark是你的朋友。它会给你一个关于多少数据的真实图像 - 以及你的应用何时发送数据。

+0

UDP发送缓冲区是否意味着一旦发生最轻微的延迟,数据包就会在发送机器上自动丢失? – 2010-04-27 19:50:04

+0

@Gene - 这是最不可能的。尽管UDP并不保证数据包能够被接收,但它肯定能保证数据包以某种形式被“发送”。如果没有发送,netstat会告诉你,我想。 [当你说“UDP缓冲区”时,你的意思是什么?我认为UDP通常没有被缓存......?] – Roddy 2010-04-27 20:19:00

+0

每个套接字(这也适用于UDP套接字)都有一个发送缓冲区,用于存储数据直到网络堆栈发送出去。应用程序可以通过setsockopt(SO_SNDBUF)影响此缓冲区的大小。当缓冲区满时,TCP发送例程块并丢弃UDP。 – 2010-04-27 20:29:23