如何利用实时数据的所有可用带宽?

How to utilize all available bandwidth with real-time data?

如何测量服务器和客户端之间的实际带宽来决定发送多少实时数据?

我的服务器向客户端发送读取时间数据,每秒 30 次。如果服务器有太多数据,它会优先处理数据块并丢弃任何不适合可用带宽的数据,因为无论如何这些数据将在下一个 tick 失效。数据通过可靠 (20%) 和不可靠通道 (80%) 发送(均基于 UDP,但如果 TCP 作为可靠通道可以提供任何好处,请告诉我)。数据对延迟高度敏感。服务器经常(但不总是!)拥有比可用带宽更多的数据。发送尽可能多的数据但不要超过可用带宽以避免数据包丢失或更高的延迟是至关重要的。

服务器和客户端是自定义应用程序,因此可以实现任何 algorithm/protocol。

我的主要问题是如何跟踪可用带宽。此外,任何有关典型带宽抖动的统计信息都会有所帮助(服务器在云端,客户是全球家庭用户)。

目前我正在考虑如何利用:

问题是这种方法太复杂了,涉及很多"heuristics",比如应该是 increase/decrease 带宽的一个步骤等等。

向过去处理过类似问题的人寻求任何建议或任何好主意

尝试使用比实际带宽更多的带宽的第一个症状是延迟增加,因为您填满了发送方和任何瓶颈之间的缓冲区。参见 https://en.wikipedia.org/wiki/Bufferbloat。我的猜测是,如果您能够在开始填满带宽并退出时成功检测到延迟增加,那么您就可以避免数据包丢失。

我不会低估 TCP - 人们花了很多时间调整它的拥塞避免以获得合理数量的可用带宽,同时仍然是一个好的网络公民。要做得更好可能并不容易。

另一方面,很大程度上取决于中间节点的态度,中间节点可能会以不同于 TCP 的方式对待 UDP。您可能会发现在负载下,它们要么优先处理 UDP,要么丢弃 UDP。此外,某些网络,尤其是卫星链接,可能会在您不知情的情况下使用 https://en.wikipedia.org/wiki/TCP_acceleration。 (这对我们来说是一个痛苦的惊喜——我们依靠 TCP 连接失败并保持活动状态来检测连接丢失。不幸的是,使用中的 TCP 加速器保持与我们的连接,假装是远端,即使连接到远端实际上丢失了)。

经过一番研究,这个问题有个名字:Congestion Control,或者Congestion Avoidance Algorithm。这是一个相当复杂的话题,并且有很多关于它的材料。 TCP Congestion Control 随着时间的推移不断发展,确实很棒。还有其他协议可以实现它,例如UDT 或 SCTP