我们有一个服务器(摄像机)通过 UDP 发送 RTSP 视频数据包。在客户站点,它会经过多个跃点,其中一个可能是不可靠的 WiFi 链接,会丢弃奇怪的数据包或五个数据包。通常这会被忽视,但有时它会杀死流几秒钟并引起客户不满(我知道,他们的 cr*p 网络在某种程度上是我们的问题......)
在使用模拟狡猾的连接进行测试时,tc
我们发现了一种奇怪的情况:如果我们在返回方向 (数据包被默默丢弃),几秒钟后,来自我们摄像机的 UDP 数据包流停止,即使 RTSP 客户端 (Live555 Wis-Streamer) 仍然相信它正在愉快地将 UDP 数据包喷射到管道中。
这很奇怪,因为显然 UDP 数据包没有被确认,并且物理链路永远不会丢失,因此我们的系统无法知道数据包正在丢弃到链上游的比特桶中,并且流媒体也无法知道没有人在收听它(流媒体会话超时直到稍后才会过期)。
编辑:我们看到 ARPing(谁有 <客户>) 此时 UDP 数据包停止传入,但在此之前没有任何数据包会告诉堆栈连接已断开。
所以我有两个问题:
- 网络堆栈是否有其他机制可以判断连接有问题?
- 在某些情况下网络堆栈是否会默默地丢弃数据包?
演示我们的测试设置:
正常状态,双向连接:
Our server <==> Switch <==> TC <==> Switch <==> PC
| |
Wireshark <-- TAP |
|
Wireshark <----------------------- TAP
故障状态,TC 丢弃返回到我们服务器的数据包:
Our server --> Switch --> TC <==> Switch <==> PC
| |
Wireshark <-- TAP |
|
Wireshark <----------------------- TAP
答案1
一旦断开连接,您应该开始接收 ICMP 目标不可达数据包,以通知您连接已断开。这是正常的 IP 行为。
有一些工具可以监视和显示 ICMP 数据包。其他工具可用于转储或捕获符合选择标准的所有流量。
使用自定义代理服务器来丢弃数据包可能会更好。
答案2
好吧,看起来是 ARP 表变得陈旧(即使我们疯狂地流式传输 UDP,但这不会引发 ARP 超时,并且在正常操作下 TCP 流量更加稀疏)增加超时可以阻止问题出现对于少于约 2 分钟的“中断”(此时 RTSP 客户端会话无论如何都会超时):
ARP gc_staletime extended from 60sec to 360sec
ARP base_unreachable time extended from 30sec to 240sec
不幸的是,这需要相当多的探索,因为我们在 Busybox 上没有arp
可用的命令,但现在对于我们正在尝试处理的情况来说,它似乎是可靠的。
我仍然热衷于了解网络堆栈的工作原理 - 目前 ARP 表/条目已过时,它会停止发送数据包,但似乎不会在尝试发送数据包的代码链中进一步导致错误。