如何调试丢包?

发布于 2024-08-30 15:51:37 字数 373 浏览 9 评论 0原文

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

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

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

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

I wrote a C++ application (running on Linux) that serves an RTP stream of about 400 kbps. To most destinations this works fine, but some destinations expericence packet loss. The problematic destinations seem to have a slower connection in common, but it should be plenty fast enough for the stream I'm sending.

Since these destinations are able to receive similar RTP streams for other applications without packet loss, my application might be at fault.

I already verified a few things:
- in a tcpdump, I see all RTP packets going out on the sending machine
- there is a UDP send buffer in place (I tried sizes between 64KB and 300KB)
- the RTP packets mostly stay below 1400 bytes to avoid fragmentation

What can a sending application do to minimize the possibility of packet loss and what would be the best way to debug such a situation ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

╰ゝ天使的微笑 2024-09-06 15:51:37

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

数据包丢失通常是由数据包缓冲区大小有限的慢速路由器引起的。如果慢速路由器有时间在接收另外 10 个数据包之前发送 10 个数据包,那么它可能能够很好地处理 1 Mbps,但如果 100 Mbps 发送方向其发送一大堆 50 个数据包,它别无选择,只能丢弃其中 40 个。

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

Don't send out packets in big bursty chunks.

The packet loss is usually caused by slow routers with limited packet buffer sizes. The slow router might be able to handle 1 Mbps just fine if it has time to send out say, 10 packets before receiving another 10, but if the 100 Mbps sender side sends it a big chunk of 50 packets it has no choice but to drop 40 of them.

Try spreading out the sending so that you write only what is necessary to write in each time period. If you have to write one packet every fifth of a second, do it that way instead of writing 5 packets per second.

明天过后 2024-09-06 15:51:37

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操作。
这可能会检测到您的路线中的慢速跳跃。在其他机器上运行它以检查与第二台机器的连接。

netstat has several usefull option to debug the situation.

First one is netstat -su (dump UDP statistics):

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

Notice "RcvbufErrors" and "SndbufErrors"

Additional option is to monitor receive and send UDP buffers of the process:

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                  *:*

Here you need to look at Recv-Q and Send-Q column of the connection you're interested. If the values high and don't drop to zero, than the process can not handle the load.

You can use these commands on sending and on receiving machine.

Also you can use mtr, which combines traceroute and ping - it pings each hop in route.
This may detect a slow hop in your route. Run it on oth machines to check connectivity to the second one.

停滞 2024-09-06 15:51:37

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

显而易见的事情要做:

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

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

RTP typically uses UDP, which is inherently lossy. Packets could be lost anywhere between sender and receiver, so local debug will show you nothing useful.

Obvious things to do:

  • a: Reduce the overall data rate
  • b: Reduce the 'peak' data rate, by
    sending small packets more often
    rather than one huge chunk every few
    seconds. ie, REDUCE your UDP send
    buffer - maybe even to just 1400
    bytes.
  • c: See if you can switch to a TCP
    variant of RTP.

If all else fails, WireShark is your friend. It will give you a true picture of how much data - and when is being sent by your app.

橪书 2024-09-06 15:51:37

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

You should try reducing the rate you send packets. A slow connection can mean all sorts of things, and trying to send it packets (small or large) at a high rate won't help.

油饼 2024-09-06 15:51:37

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

This may not be the answer you want, but if I had packet loss problems I'd try to switch my application to use TCP, and have most worries of packet loss taken off my mind.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文