我必须尽可能快速和实时地通过 UDP 发送一系列视频帧,当我掌握了基础知识时,我遇到了各种各样的困难。我的一些目标:
数据通常通过拨号发送(因此是 UDP 而不是 TCP),但还需要支持快速以太网。
偶尔丢帧是可以的(因此使用 UDP 而不是 TCP)。
需要低延迟。远程接收的帧应该是最近发送的帧(在缓冲区中等待的帧不超过几帧)。
我需要能够检测有效带宽,以便我可以或多或少地压缩帧以保持帧速率。
我已经设法实现了大部分部分:
我将帧数据分解为一个或多个大约 500 字节的数据报,每个数据报都有一个序列号和其他信息。接收器重新组合整个帧并检测是否有任何数据报丢失。
如果接收方检测到超过一定百分比的丢帧(例如,过去 10 帧中的 50%),我会向发送方发送一条 TCP 消息以减慢 50%。发送者在随后的每一帧中缓慢地将速度提高 5%。
使用 System.Net.Sockets.UdpClient 发送和接收数据。
我有一个单独的 TCP 通道,用于控制返回给发送者的消息。
我现在的主要困难是检测有效带宽和处理延迟,尤其是在拨号时(最大约 4,000 字节/秒)。例如,如果我尝试使用 TcpClient.Send() 发送 100,000 字节/秒,它们似乎都到达(没有丢弃的数据报),但在最后一个数据报到达时延迟很大。我认为 TcpClient.Send() 函数会阻塞,直到缓冲区能够发送这弄乱了我当前的算法。
任何人都可以向我指出任何信息来源,以了解如何:
检测 UDP 上的实际带宽。
用于动态调整带宽以适应可用管道的更好算法。
以所需带宽平稳发送数据。
一种检测延迟并将延迟降至最低的方法。
上周我一直在转动我的轮子,每次我解决一个问题时,似乎另一个问题就会抬头。