速读原著-TCP/IP(往返时间RTT的例子)

2020-03-13 11:56:24 浏览数 (1)

第21章 TCP的超时与重传

21.4 往返时间RTT的例子

在本章中,我们将使用以下这些例子来检查 T C P的超时和重传、慢启动以及拥塞避免等方方面面的实现细节。 使用s o c k程序和如下的命令来将 3 2 7 6 8字节的数据从主机s l i p发送到主机v a n g o g h . c s .b e r k e l e y . e d u上的丢弃服务。

代码语言:javascript复制
slip % sock -D -i -n32 vangogh.cs.berkeley.edu discard

在扉页前图中,可以看到 s l i p通过两个 S L I P链路与1 4 0 . 2 5 2 . 1以太网相连,并从这里通过I n t e r n e t到达目的地。通过使用两个 9600 b/s的S L I P链路,我们期望能够得到一些可测量的时延。

该命令执行3 2个写1 0 2 4字节的操作。由于s l i p和b s d i之间的M T U为2 9 6字节,因此这些操作会产生1 2 8个报文段,每个报文段包含 2 5 6字节的用户数据。整个传输过程的时间约为 4 5秒,我们观察到了一个超时和三次重传。

当该传输过程进行时,我们在 s l i p上使用t c p d u m p来截获所有的发送和接收的报文段,并通过使用 - D选项来打开插口排错功能(见 A . 6节),这样便可以通过运行一个修改后的t r p t( 8 )程序来打印出连接控制块中与 RT T、慢启动及拥塞避免等有关的多个变量。

对于给出的跟踪结果,我们不能够完全进行显示,相反,我们将在介绍本章时看到它的各个部分。图2 1 - 2显示的是前5秒中的数据和确认的传输过程。与前面 t c p d u m p的输出相比,我们已对其显示稍微进行了修改。虽然我们仅能够在运行 t c p d u m p的主机上测量分组发送和接收的时间,但在本图中我们希望显示出分组正在网络中传输(它们确实存在,因为这个局域网连接与共享式的以太网并不一样)以及接收主机何时可能产生 A C K(在本图中去掉了所有的窗口大小通告。主机 s l i p总是通告窗口大小为 4 0 9 6,而v a n g o g h则总是通告窗口大小为8 1 9 2)。

还需要注意的是在本图中我们已经将报文段按照在主机 s l i p上发送和接收的序号记为1 ~ 1 3和1 5。这与在这个主机上所收集的 t c p d u m p的输出结果有关。

21.4.1 往返时间RTT的测量

在图2 1 - 2左边的时间轴上有三个括号,它们表明为进行RT T计算对哪些报文段进行了计时,并不是所有的报文段都被计时。

大多数源于伯克利的T C P实现在任何时候对每个连接仅测量一次 RT T值。在发送一个报文段时,如果给定连接的定时器已经被使用,则该报文段不被计时。

在每次调用 500 ms的T C P的定时器例程时,就增加一个计数器来完成计时。这意味着,如果一个报文段的确认在它发送 550 ms后到达,则该报文段的往返时间 RT T将是1个滴答(即500 ms)或是2个滴答(即1000 ms)。

对每个连接而言,除了这个滴答计数器,报文段中数据的起始序号也被记录下来。当收到一个包含这个序号的确认后,该定时器就被关闭。如果 A C K到达时数据没有被重传,则被平滑的RT T和被平滑的均值偏差将基于这个新测量进行更新。

图2 1 - 2中连接上的定时器在发送报文段 1时启动,并在确认(报文段 2)到达时终止。尽管它的RT T是1 . 0 6 1秒(t c p d u m p的输出),但插口排错的信息显示该过程经历了 3个T C P时钟滴答,即RT T为1500 ms。

下一个被计时的是报文段 3。当2.4 ms后传输报文段4时,由于连接的定时器已经被启动,因此该报文段不能被计时。当报文段 5到达时,确认了正在被计时的数据。虽然我们从t c p d u m p的输出结果可以看到其RT T是0 . 8 0 8秒,但它的RT T被计算为1个滴答(500 ms)。

定时器在发送报文段 6时再次被启动,并在 1 . 0 1 5秒后接收到它的确认(报文段 1 0)时终止。测量到的RT T是2个滴答。报文段7和9不能被计时,因为定时器已经被使用。而且,当收到报文段8(第7 6 9字节的确认)时,由于该报文段不是正在计时的数据的确认,因此什么也没有进行更新。

图2 1 - 3显示了本例中通过t c p d u m p的输出所得到的实际RT T与时钟滴答计数之间的关系。

在图的上端表示间隔为 500 ms的时钟滴答,图的下端表示 t c p d u m p的输出时间及定时器何时被启动和关闭。在发送报文段 1和接收到报文段 2之间经历了 3个滴答,时间为 1 . 0 6 1秒,因此假定第1个滴答发生在0 . 0 3秒处(第1个滴答一定在0 ~ 0 . 0 6 1秒之间)。接着该图表示了第 2个被测量的RT T为什么被记为1个滴答,而第3个被记为2个滴答。

在这个完整的例子中, 1 2 8个报文段被传送,并收集了 1 8个RT T采样。图2 1 - 4表示了测量的RT T(取自t c p d u m p的输出)和 T C P为超时所使用的 RTO(取自插口排错的输出)。在图2 1 - 2中,x轴从时间0开始,表示的是传输报文段 1的时刻,而不是传输第1个S Y N的时刻。

测量出RT T的前3个数据点对应图2 1 - 2所示的3个RT T。在时间10, 14和2 1处的间隔是由在这些时刻附近发生的重传(将在本章后面给出)引起的。 K a r n算法在另一个报文段被发送和确认之前阻止我们更新估计器。同样注意到在这个实现中, T C P计算的RTO总是500 ms的倍数。

21.4.2 RTT估计器的计算

让我们来看一下RT T估计器(平滑的RT T和平滑的均值偏差)是如何被初始化和更新,以及每个重传超时是怎样计算的。

变量A和D分别被初始化为0和3秒。初始的重传超时使用下面的公式进行计算(因子2D只在这个初始化计算中使用。正如前面提到的,以后使用4D和A相加来计算RTO)。

这就是传输初始S Y N所使用的RTO。结果是这个初始S Y N丢失了,然后超时并引起了重传。图 2 1 - 5给出了t c p d u m p输出文件中的前4行。

当超时在5 . 8 0 2秒后发生时,计算当前的RTO值为

代码语言:javascript复制
RTO = A   4D = 0   4×3 = 12 s

因此,应用于 RTO的指数退避取为 1 2。由于这是第 1次超时,我们使用倍数 2,因此下一个超时时间取值为2 4秒。再下一个超时时间的倍数为 4,得出值为4 8秒(这些初始RTO,对于一个连接上的最初的S Y N,取值为6秒,接下来为2 4秒,正是我们在图4 - 5中看到的)。

A C K在重传后4 6 7 m s到达。A和D的值没有被更新,这是因为 K a r n算法对重传的处理比较模糊。下一个发送的报文段是第 4行的A C K,但它只是一个 A C K,所以没有被计时(只有数据报文段才会被计时)。

当发送第1个数据报文段时(图 2 1 - 2中的报文段1),RTO没有改变,这同样是由于 K a r n算法。当前的2 4秒一直被使用,直到进行一个 RT T测量。这意味着图 2 1 - 4中时间0的RTO并不真的是2 4,但我们没有画出那个点。当第1个数据报文段的A C K(图2 1 - 2中的报文段2)到达时,经历了3个时钟滴答,估计器被初始化为

代码语言:javascript复制
A = M   0.5 = 1.5   0.5 = 2
D = A/2 = 1

(因为经历3个时钟滴答,因此, M取值为1 . 5)。在前面,A和D初始化为0,RTO的初始计算值为3。这是使用第1个RT T的测量结果M对估计器进行首次计算的初始值。计算的 RTO值为

代码语言:javascript复制
RTO = A   4D = 2   4×1 = 6 s

当第2个数据报文段的A C K(图2 1 - 2中的报文段5)到达时,经历了1个时钟滴答(0 . 5秒),估计器按如下更新:

代码语言:javascript复制
E rr = M -A = 0.5 - 2 =-1 . 5
A = A   g E rr = 2-0 . 1 2 5×1.5 = 1.8125
D = D   h(| E rr | - D) = 1   0.25×( 1 . 5-1) = 1.125
RTO = A   4D = 1.8125   4×1.125 = 6.3125

E rr、A和D的定点表示与实际使用的定点计算(在简化浮点计算中表示过)有一些微小的差别。这些不同使 RTO取值为6秒(而非6 . 3 1 2 5秒),正如我们在图 2 1 - 4中的时间1 . 8 7 1处所画的那样。

21.4.3 慢启动

我们在第2 0 . 6节介绍了慢启动算法,在图 2 1 - 2中可再次看到它的工作过程。连接上最初只允许传输一个报文段,然后在发送下一个报文段之前必须等待接收它的确认。当报文段2被接收后,就可以再发送两个报文段。

0 人点赞