《第20章TCP的成块数据流》由会员分享,可在线阅读,更多相关《第20章TCP的成块数据流(16页珍藏版)》请在金锄头文库上搜索。
1、下载第20章TCP的成块数据流20.1引言在第15章我们看到 TFTP使用了停止等待协议。数据发送方在发送下一个数据块之前需要 等待接收对已发送数据的确认。本章我们将介绍 TCP所使用的被称为滑动窗口协议的另一种 形式的流量控制方法。该协议允许发送方在停止并等待确认前可以连续发送多个分组。由于 发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。我们还将介绍 TCP的PUSH标志,该标志在前面的许多例子中都出现过。此外,我们还要 介绍慢启动, TCP使用该技术在一个连接上建立数据流,最后介绍成块数据流的吞吐量。20.2正常数据流我们以从主机 svr4单向传输 8192个字节到
2、主机 bsdi开始。在 bsdi上运行 sock程序作 为服务器:bsdi % sock -i -s 7777 其中,标志 -i和-s指示程序作为一个“吸收( sink)”服务器运行(从网络上读取并丢弃 数据),服务器端口指明为 7777。相应的客户程序运行为:svr4 % sock -i -n8 bsdi 7777 该命令指示客户向网络发送 8个1024字节的数据。图 20-1显示了这个过程的时间系列。我 们在输出的前 3个报文段中显示了每一端 MSS的值。发送方首先传送 3个数据报文段( 46)。下一个报文段( 7)仅确认了前两个数据报文段, 这可以从其确认序号为 2048而不是3073看
3、出来。报文段7的ACK的序号之所以是 2048而不是3073是由以下原因造成的:当一个分组到达时, 它首先被设备中断例程进行处理,然后放置到 IP的输入队列中。三个报文段 4、5和6依次到达 并按接收顺序放到 IP的输入队列。 IP将按同样顺序将它们交给 TCP。当 TCP处理报文段 4时, 该连接被标记为产生一个经受时延的确认。 TCP处理下一报文段( 5),由于TCP现在有两个未 完成的报文段需要确认,因此产生一个序号为 2048的ACK(报文段 7),并清除该连接产生经 受时延的确认标志。 TCP处理下一个报文段( 6),而连接又被标志为产生一个经受时延的确 认。在报文段9到来之前,由于
4、时延定时器溢出,因此产生一个序号为 3073的ACK(报文段 8)。 报文段 8中的窗口大小为 3072,表明在 TCP的接收缓存中还有 1024个字节的数据等待被应用程 序读取。报文段1116说明了通常使用的“隔一个报文段确认”的策略。报文段 11、12和13到达并 被放入 IP的接收队列。当报文段 11被处理时,连接被标记为产生一个经受时延的确认。当报 文段12被处理时,它们的 ACK(报文段 14)被产生且连接的经受时延的确认标志被清除。报 文段13使得连接再次被标记为产生经受时延。但在时延定时器溢出之前,报文段 15处理完毕, 因此该确认立刻被发送。图20-1 从svr4 传输8192
5、个字节到bsdi注意到报文段 7、14和16中的ACK确认了两个收到的报文段是很重要的。使用 TCP的滑动 窗口协议时,接收方不必确认每一个收到的分组。在 TCP中,ACK是累积的它们表示接 收方已经正确收到了一直到确认序号减 1的所有字节。在本例中,三个确认的数据为 2048字节 而两个确认的数据为 1024字节(忽略了连接建立和终止中的确认)。用tcpdump看到的是 TCP的动态活动情况。我们在线路上看到的分组顺序依赖于许多无 法控制的因素:发送方 TCP的实现、接收方 TCP的实现、接收进程读取数据(依赖于操作系统 的调度)和网络的动态性(如以太网的冲突和退避等)。对这两个TCP而言,
6、没有一种单一的、 正确的方法来交换给定数量的数据。为显示情况可能怎样变化,图 20-2显示了在同样两个主机之间交换同样数据时的另一个 时间系列,它们是在图 20-1所示的几分钟之后截获的。一些情况发生了变化。这一次接收方没有发送一个序号为 3073的ACK,而是等待并发送 序号为 4097的ACK。接收方仅发送了 4个ACK(报文段 7、10、12和15):三个确认了 2048字节,另一个确认了 1024字节。最后 1024字节数据的 ACK出现在报文段 17中,它与 FIN的ACK一道发送(比较该图中的报文段 17与图20-1中的报文段 16和18)。图20-2 从svr4 到bsdi 的另
7、外8192字节数据的传输过程快的发送方和慢的接收方图20-3显示了另外一个时间系列。这次是从一个快的发送方(一个 Sparc工作站)到一个 慢的接收方(配有慢速以太网卡的 80386机器)。它的动态活动情况又有所不同。发送方发送 4个背靠背( back-to-back)的数据报文段去填充接收方的窗口,然后停下来 等待一个 ACK。接收方发送 ACK(报文段 8),但通告其窗口大小为 0,这说明接收方已收到 所有数据,但这些数据都在接收方的 TCP缓冲区,因为应用程序还没有机会读取这些数据。 另一个 ACK(称为窗口更新)在 17.4 ms后发送,表明接收方现在可以接收另外的 4096个字节 的
8、数据。虽然这看起来像一个 ACK,但由于它并不确认任何新数据,只是用来增加窗口的右 边沿,因此被称为窗口更新。发送方发送最后 4个报文段( 1013),再次填充了接收方的窗口。注意到报文段 13中包括 两个比特标志: PUSH和FIN。随后从接收方传来另外两个 ACK,它们确认了最后的 4096字节 的数据(从 4097到8192字节)和 FIN(标号为 8192)。图20-3 从一个快发送方发送8192字节的数据到一个慢接收方20.8 滑动窗口图20-4用可视化的方法显示了我们在前一节观察到的滑动窗口协议。提供的窗口 由接收方通告可用的窗口发送并被确认不能够发送,发送,但未被确认直至窗口移动
9、 能够发送ASAP图20-4 TCP滑动窗口的可视化表示在这个图中,我们将字节从 1至11进行标号。接收方通告的窗口称为提出的窗口( offered window),它覆盖了从第 4字节到第 9字节的区域,表明接收方已经确认了包括第 3字节在内的 数据,且通告窗口大小为 6。回顾第 17章,我们知道窗口大小是与确认序号相对应的。发送方 计算它的可用窗口,该窗口表明多少数据可以立即被发送。当接收方确认数据后,这个滑动窗口不时地向右移动。窗口两个边沿的相对运动增加或 减少了窗口的大小。我们使用三个术语来描述窗口左右边沿的运动:1) 称窗口左边沿向右边沿靠近为窗口合拢。这种现象发生在数据被发送和确认
10、时。2) 当窗口右边沿向右移动时将允许发送更多的数据,我们称之为窗口张开。这种现象发 生在另一端的接收进程读取已经确认的数据并释放了 TCP的接收缓存时。3) 当右边沿向左移动时,我们称之为窗口收缩。 Host Requirements RFC强烈建议不要使 用这种方式。但 TCP必须能够在某一端产生这种情况时进行处理。第 22.3节给出了这样的一个 例子,一端希望向左移动右边沿来收缩窗口,但没能够这样做。,图20-5表示了这三种情况。因为窗口的左边 沿受另一端发送的确认序号的控制,因此不可能 向左边移动。如果接收到一个指示窗口左边沿向 左移动的 A C K ,则它被认为是一个重复 A C K
11、 并被丢弃。合拢收缩张开窗口图20-5 窗口边沿的移动如果左边沿到达右边沿,则称其为一个零窗口,此时发送方不能够发送任何数据。一个例子图20-6显示了在图 20-1所示的数据传输过程中滑动窗口协议的动态性。由第2个报文段通告的窗口在第4,5,6报文段中发送的数据被第7报文段确认由第7个报文段通告的窗口 被第8报文段确认由第8个报文段通告的窗口在第9报文段 中发送的数据被第10报文段确认由第10个报文段通告的窗口在第11,12,13报文段 中发送的数据被第14报文段确认由第14个报文段 通告的窗口在第15报文段中发送的数据 被第16报文段确认图20-6 图20-1的滑动窗口协议以该图为例可以总结
12、如下几点:1) 发送方不必发送一个全窗口大小的数据。2) 来自接收方的一个报文段确认数据并把窗口向右边滑动。这是因为窗口的大小是相对 于确认序号的。3) 正如从报文段 7到报文段 8中变化的那样,窗口的大小可以减小,但是窗口的右边沿却 不能够向左移动。4) 接收方在发送一个 ACK前不必等待窗口被填满。在前面我们看到许多实现每收到两个 报文段就会发送一个 ACK。下面我们可以看到更多的滑动窗口协议动态变化的例子。20.9 窗口大小由接收方提供的窗口的大小通常可以由接收进程控制,这将影响 TCP的性能。 4.2BSD默认设置发送和接受缓冲区的大小为 2048个字节。在4.3BSD中双方被增加为
13、4096个字节。正如我们在本书中迄今为止所看到的例子一样,SunOS 4.1.3 、BSD/386和SVR4仍然使用4096字节的默认大小。其他的系统,如Solaris 2.2、4.4BSD和 AIX3.2则使用更大的默认缓存大小,如8192或16384等。插口API允许进程设置发送和接收缓存的大小。接收缓存的大小是该连接上所能够通告的最大窗口大小。有一些应用程序通过修改插口缓存大小来增加性能。Mogul 1993显示了在改变发送和接收缓存大小(在单向数据流的应用中,如文件传输, 只需改变发送方的发送缓存和接收方的接收缓存大小)的情况下,位于以太网上的两个工作 站之间进行文件传输时的一些结果。
14、它表明对以太网而言,默认的 4096字节并不是最理想的 大小,将两个缓存增加到 16384 个字节可以增加约 40%左右的吞吐量。在 Papadopoulos和 Parulkar 1993中也有相似的结果。在20.7节中,我们将看到在给定通信媒体带宽和两端往返时间的情况下,如何计算最小的 缓存大小。一个例子可以使用 sock程序来控制这些缓存的大小。我们以如下方式调用服务器程序:bsdi % sock -i -s -R6144 5555 该命令设置接收缓存为 6144个字节( -R选项)。接着我们在主机 sun上启动客户程序并使 之发送8192个字节的数据:sun % sock -i -n1
15、-w8192 bsdi 5555 图20-7显示了结果。首先注意到的是在报文段 2中提供的窗口大小为 6144字节。由于这是一个较大的窗口,因 此客户立即连续发送了 6个报文段( 49),然后停止。报文段 10确认了所有的数据(从第 1到 6144字节),但提供的窗口大小却为 2048,这很可能是接收程序没有机会读取多于 2048字节的 数据。报文段 11和12完成了客户的数据传输,且最后一个报文段带有 FIN标志。报文段 13包含与报文段 10相同的确认序号,但通告了一个更大的窗口大小。报文段 14确 认了最后的 2048字节的数据和 FIN,报文段 15和16仅用于通告一个更大的窗口大小。报文段17和18完成通常的关闭过程。图20-7 接收方提供一个6144字节的接收窗口的情况下的数据传输20.10 PUSH标志在每一个 TCP例子中,我们都看到了 PUSH标志,但一直没有介绍它的用途。发送方