测量网络传输时间

6
我已经开发了一个服务器和客户端应用程序,使用RTSP从一端流式传输视频帧到另一端。现在,为了收集有助于改进我的应用程序的统计数据,我需要测量发送帧和接收帧之间的经过时间。
目前我正在使用以下公式:
Client_Receive_Timestamp - Server_Send_Timestamp = Elapsed_Time

问题

我觉得经过时间大约比实际时间多了100-200毫秒。我认为原因是服务器时钟和客户端时钟不同步,相差大约100-200毫秒。

问题

如何准确地测量两台机器之间的经过时间?

主题Accurately measuring elapsed time between machines建议计算往返延迟时间。但是,我无法使用此解决方案,因为客户端不请求帧,它只通过RTSP接收帧。


你能否解释一下为什么无法计算往返延迟?你是否被迫使用RTSP流作为唯一的网络连接?如果不是,你可以使用不同网络连接上的简单ping来估计往返时间。 - Lukas Boersma
使用第三方机器并确认您的疑虑。 - lsalamon
@LukasBoersma 我的目标是测量传输帧所需的时间,而不是测量发送和接收单个数据包所需的时间。 - chrisp
1
你将当前时间发送到第二台机器。当它在那里接收到时,加上往返时间的一半来估计发送机器上的当前时间。多次执行此操作并取中位数以减少噪音。有关详细信息,请查看NTP协议,该协议基本上就是这样做的。 - Lukas Boersma
1
请注意,RTSP([RFC2326](https://tools.ietf.org/html/rfc2326))是一种用于在终端之间建立和控制媒体会话的协议 - 而不是用于传输媒体流本身的协议。媒体流通常(但不必须)使用RTP传输协议([RFC3550](https://tools.ietf.org/html/rfc3550))进行传输,其伴随控制协议RTCP(在同一RFC中)指定了报告传输延迟到源端点的方法,考虑到可扩展性等问题。值得一看。 - Jeremy
显示剩余4条评论
2个回答

4

假设:

那么,您可以简单地从“发送时间戳”中减去“接收时间戳”以获得延迟持续时间。观察到的误差将小于两个时钟误差之和。如果时间尺度足够小(可能小于一小时),您可以合理地忽略旋转效应

如果在两台机器上ntpd没有运行,并且您拥有必要的权限,则可以

$ sudo ntpdate -v pool.ntp.org

强制与公共时间服务器池同步。
然后,您可以使用c++11的high_resolution_clock来计算持续时间:
/* hrc.cc */
#include <chrono>
#include <iostream>

int main(int,char**){
  using std::chrono::high_resolution_clock;
  // send something                                                                                                                      
  high_resolution_clock::time_point start = high_resolution_clock::now();
  std::cout << "time this" << std::endl ;
  // receive something                                                                                                                   
  high_resolution_clock::time_point stop = high_resolution_clock::now();
  std::cout
    << "duration == "
    << std::chrono::duration_cast<std::chrono::nanoseconds>(stop-start).count()
    << "ns"
    << std::endl
    ;
  return 0;
}

这是在我的系统上看到的先前示例的样子:
$ make hrc && ./hrc
c++     hrc.cc   -o hrc
time this
duration == 32010ns

3

我需要测量发送帧和接收帧之间的经过时间。

您不需要精确的时间戳。您可以平均估计延迟时间。

如果A将数据包(或帧)发送给B,B立即响应(*)

A(发送时间) ---> B ---> A(接收时间)

然后您可以轻松地计算延迟时间:

latency = (receivedTime - sendTime) / 2

这当然是在延迟对称的情况下。如果您研究“网络延迟估算算法”短语,可以找到更详细的算法。
有了估计的延迟时间,您当然可以估计时间差(但这似乎不是必要的):
A(发送时间) ---> B(接收时间B) --(接收时间B)--> A
timeDelta = sendTime + latency - receivedTimeB

请注意,即使您平均许多结果,此算法可能极具偏见。这只是发表了一个简单的例子来说明一般想法。

(*) 它不会立即发生实际上引起了误差。这取决于机器B的负载程度。


这里的问题是我不能只用一个数据包来响应。我需要通过发送整个帧回到服务器来响应,因为传输整个帧(=多个数据包)需要更长的时间。 - chrisp
1
@Chris。这里的“ping”数据包是无关紧要的。如果你能让B立即响应,那么发送什么并不重要。你可以使用帧来进行完全相同的计算。因此,您可以在线执行测量,同时传输数据。或者,如果您需要在传输发生之前执行该操作,则可以使用N个大小不同的数据包,并估计延迟随数据包大小增加而增长的速度。这将使您能够估计任意帧大小的延迟。 - BartoszKP
听起来是个好主意。然而,在问题下面提到的评论中提到的解决方案似乎更容易实现。 - chrisp
@Chris。评论中的解决方案假定您知道往返时间。因此,它与我在帖子末尾发布的解决方案(估计“timeDelta”)相同。发送“sendTime”与发送“当前时间”相同。 - BartoszKP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接