2010-09-19 80 views
5

我必须尽可能快速和实时地通过UDP发送一系列视频帧,并在基本工作时,我遇到了各种各样的困难。我的一些目标:如何通过UDP发送实时数据?

  1. 数据通常会通过拨号发送(因此UDP而不是TCP),但也需要支持快速以太网。

  2. 可以偶尔丢弃帧(因此UDP而不是TCP)。

  3. 需要低延迟。远程接收的帧应该是最近发送的帧(缓冲区中不超过几帧)。

  4. 我需要能够检测有效带宽,以便我可以或多或少地压缩帧以保持帧速率。

我已成功地实现大多数件:

  1. 我分手帧数据成约500个字节的一个或多个数据报,并且每个都有一个序列号和其他信息。接收器重新组装整个帧并检测是否有数据报丢失。

  2. 如果接收方检测到丢失帧的比例超过了一定比例(例如,在过去10帧中为50%),我会向发送方发送TCP消息以减慢50%。发送者比每个后续帧慢慢增加5%的速度。

  3. 使用System.Net.Sockets.UdpClient发送和接收数据。

  4. 我有一个单独的TCP通道用于控制消息回发给发件人。

我现在的主要困难是检测有效带宽并处理延迟,特别是在拨号(最大约4000字节/秒)时处理延迟。例如,如果我尝试使用TcpClient.Send()发送100,000字节/秒,则它们似乎都到达(没有丢弃的数据报),但是到最后一个数据报到达时有很大的延迟。我认为TcpClient.Send()函数是阻塞的,直到缓冲区能够发送使我当前的算法变得混乱。

任何人都可以点我的任何信息来源如何:

  1. 通过UDP检测实际带宽。

  2. 一个更好的动态调整带宽以适应可用管道的算法。

  3. 以期望的带宽顺利发送数据。

  4. 一种检测延迟降至最低的方法。

上周我一直在旋转我的车轮,每当我解决一个问题时,它似乎是另一个问题。

回答

2

您也可以为每个数据包添加一个时间戳。然后你可以检测延迟是否增加。在这种情况下,您发回消息以减少带宽。

在创建连接时,您只需检测很少数据包的延迟。这个值在运行时不应该改变。

+0

我确定检测延迟将需要某种数据报时序。例如,我可能需要附加一个时间戳,发送给接收者,然后发送回(可能使用TCP控制通道)。在某种历史队列中查找原始发送时间,差异/ 2是aprox。潜伏。我无法找到已发布的算法来完成此操作,因此我可以高效地实施。 – 2010-09-19 19:13:45

+0

你甚至不需要知道绝对延迟。由于它是你想要解决的带宽问题,你可以看看帧间时间 - 如果帧间隔为40毫秒,但你看到它们相距90毫秒,那么发送者需要放慢速度。 – caf 2010-09-20 04:23:48

+0

问题在于,随着时间的推移,小的延迟可能会在帧发送之间产生大的延迟。我最终发送了一个ACK每收到一个完整的帧。在发件人处,我会跟踪最近发送的10个帧,发送时间和确认时间。如果平均时间太长,那么我知道要放慢速度。 – 2010-09-27 03:01:29