5-7 TCP可靠传输的实现

TCP 基于以字节为单位的滑动窗口来实现可靠传输。

我们来举例说明,这是因特网上的两台主机,它们之间已经建立了一个 TCP 连接。为了简单起见,我们假定数据传输只在一个方向进行。换句话说,发送方给接收方发送 TCP 数据报文段,接收方给发送方发送相应的 TCP 确认报文段。这样的好处是实讨论仅限于两个窗口,也就是发送方的发送窗口和接收方的接收窗口。

TCP 的滑动窗口是以字节为单位的,如图所示,这是发送方待发送数据字节的序号。为了方便讲解和在有限的屏幕上显示更多的字节序号,字节序号的值都取得很小。现在,假设发送方收到了一个来自接收方的确认报文段,在报文段首部中的窗口字段的值为20,也就是接收方表明自己的接收窗口的尺寸为20,字节确认号字段的值为31,这表明接收方希望收到下一个数据的序号是31,而序号 30 为止的数据已经全部正确接收了。因此,发送方根据这两个字段的值构造出自己的发送窗口,如图所示。

01:48
为了简单起见,我们假定网络不存在拥塞问题,也就是发送方在构造自己的发送窗口时,仅考虑接收方的接收窗口,而不考虑拥塞窗口。由于本例中接收方告诉发送方自己的接收窗口尺寸为20,因此发送方将自己的发送窗口尺寸也设置为20。发送方在没有收到接收方确认的情况下,可以把发送窗口内的数据依次全部发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。这是发送窗口的后延,这是发送窗口的前沿。发送窗口后沿的后面部分是已发送并已收到确认的数据字节的序号,这些数据字节显然不需要再保存在发送缓存中了,可以将它们删除。发送窗口前沿的前面部分是当前不允许发送的数据字节的序号。

03:00
我们来看看发送窗口后延的移动情况,有以下两种可能,一种是不动,也就是没有收到新的确认,发送窗口的后延不会移动。另一种是向前移动,也就是收到了新的确认,发送窗口的后延向前移动。发送窗口的后延不可能向后移动,因为不能撤销掉已收到的确认。再来看发送窗口前沿的移动情况,有以下三种可能,通常情况下,发送窗口的前沿是不断向前移动的,但也有可能不动。一种是由于没有收到新的确认,接收方通知的窗口大小也没有改变。另一种是收到了新的确认,可向前移动相应位置,但接收方通知的窗口缩小了,前沿应该向后回缩。如果向前移动和向后回缩的尺寸恰好相等,就会使得发动窗口的前沿不动,发送窗口的前沿还可能向后收缩,这发生在接收方通知的窗口变小了。

04:19
但 TCP 标准强烈不赞成这样做,因为很可能发送方在收到这个通知之前就已经发送了窗口中的许多数据。现在又要收缩窗口不让发送这些数据,显然就会产生错误。现在,假定发送方将发送窗口内序号 31- 41 的数据封装在几个不同的报文段中发送出去,此时发送窗口的位置并没有改变。发送窗口内序号 31- 41 的数据已经发送,但未收到确认,而序号 42- 50 的数据是允许发送但还未发送的。

05:07
请同学们思考一下,我们如何描述发送窗口的状态?换句话说,如果我们要编程实现滑动窗口机制,那么对于发送窗口的状态应该如何标记和维护呢?如图所示,可以使用三个指针,P1、P2、 P3 分别指向相应的字节序号。这样,小于 P1 的就是已发送并已收到确认的部分。大于等于 P3 的是不允许发送的部分。 P3 减P1,可以得出当前发送窗口的尺寸。 P2 减P1,可以得出已发送但尚未收到确认的字节数量。 P3 减P2,可以得出允许发送但当前尚未发送的字节数量。

06:08
我们再来看看接收方的接收窗口,它的尺寸为20。在接收窗口外面到 30 号为止的数据是已经发送过相应确认并已交付给应用进程的数据,因此无需再保留这些数据,可将它们从接收缓存中删除了。接收窗口内 31- 50 号数据是允许接收的数据。接收窗口外 51 号及其后续数据目前不允许接收。假设发送方之前发送的封装有 32 和 33 号数据的报文段到达了接收方。由于数据序号落在接收窗口内,所以接收方接受他们,并将他们存入接收缓存。但是他们是为按需到达的数据,因为 31 号数据还没有到达,这有可能是丢了,也有可能是滞留在网络中的某处。

07:14
请注意,接收方只能对按序收到的数据中的最高序号给出确认,因此接收方发出的确认报文段中的确认序号仍然是31,也就是希望收到 31 号数据窗口字段的值仍是20,表明接收方没有改变自己接收窗口的大小。发送方收到该确认报文段后,发现这是一个针对 31 号数据的重复确认,就知道接收方收到了未按需到达的数据。由于这是针对 31 号数据的第一个重复确认,因此这并不会引起发送方针对该数据的快重传。另外,接收方通知的窗口尺寸仍是20,因此发送方保持自己的发送窗口尺寸为20。

08:12
现在,假设封装有 31 号数据的报文段到达了,接收方接受该报文段,将其封装的 31 号数据存弱接收缓存。接收方现在可将接收到的 31- 33 号数据交付给应用进程,然后将接收窗口向前移动三个序号,并给发送方发送确认报文段。该确认报文段中窗口字段的值仍为20,表明接收方没有改变自己接收窗口的大小。确认号字段的值为34,这表明接收方已经收到了序号 33 为止的全部数据,现在假设又有几个数据报文段到达了接收方,他们封装有 3738 以及 40 号数据。这些数据的序号虽然落在接收窗口内,但他们都是为按需到达的数据,只能先暂存在接收缓存中。

09:20
假设接收方先前发送的确认报文段到达了发送方,发送方接收后,将发送窗口向前滑动,三个序号发送窗口的尺寸保持不变,这样就有新序号 51- 53 落入发送窗口内,而序号 31- 33 移出了发送窗口。现在可将 31- 33 号数据从发送缓存中删除了,因为已经收到了接收方。针对他们的确认,发送方继续将发送窗口内序号 42- 53 的数据封装在几个不同的报文段中发送出去。现在发送窗口内的序号已经用完了,发送方在未收到接收方发来确认的情况下,不能再发送新的数据。序号落在发送窗口内的已发送数据如果迟迟收不到接收方的确认,则会产生超时重传。接下来,我们还要对 TCP 可靠传输的实现做几点补充说明。

10:35
第一点,虽然发送方的发送窗口是根据接收方的接收窗口设置的,但在同一时刻,发送方的发送窗口并不总是和接收方的接收窗口一样大。这是因为网络传送窗口值需要经历一定的时间滞后,并且这个时间还是不确定的。另外,发送方还可能根据网络当时的拥塞情况,适当减小自己的发送窗口尺寸。

11:10
第二点,对于不按需到达的数据应如何处理? TCP 并无明确规定。如果接收方把不按需到达的数据一律丢弃,那么接收窗口的管理将会比较简单。但这样做对网络资源的利用不利,因为发送方会重复传送较多的数据。 TCP 通常对不按需到达的数据是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,在暗序交付上层的应用进程。

11:51
第三点, TCP 要求接收方必须有累计确认和捎带确认机制,这样可以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。但是接收方不应过分推迟发送确认,否则会导致发送方不必要的超时重传,这反而浪费了网络资源。 TCP 标准规定,确认推迟的时间不应超过 0. 5 秒。若收到一连串具有最大长度的报文段,则必须每隔一个报文段就发送一个确认。另外,捎带确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据。

12:50
第四点, TCP 的通信是全双工通信,通信中的每一方都在发送和接收报文段,因此每一方都有自己的发送窗口和接收窗口。在谈到这些窗口时,一定要弄清楚是哪一方的窗口。最后,我们来做两个相关的习题,这是计算机专业考研全国统考计算机网络部分 2009 年的题。38,请同学们暂停播放视频思考一下,给出你的答案。答案是选项d,大家都选对了吗?我们来一起分析一下。根据提议可知,这是主机甲给主机乙发送的第一个数据报文段,其首部中序号字段的值为200,也就是说,其数据载荷的第一个字节的序号为200。由于数据载荷共有 300 个字节,因此数据载荷的最后一个字节的序号为499,这是主机甲给主机乙发送的第二个数据报文段的数据载荷部分。由于前一个报文段数据载和的最后一个字节的序号是499,因此,本报文段数据载和的第一个字节的序号应为500,相应的,其首部中序号字段的值应为500。由于数据载荷共有 500 个字节,因此数据载荷的最后一个字节的序号为999,这是主机乙给主机甲发送的确认报文段的首部,其中确认序号字段的值为1000。这是因为主机乙目前已经按序正确接收了序号到 999 为止的全部数据,现在希望接收序号为 1000 及其后续的数据。该确认报文段实际上是对已正确接收的 2 个 TCP 数据报文段的累积确认。

15:12
再来看 2011 年的题40,请同学们暂停播放视频,思考一下,给出你的答案。答案是选项b,大家都选对了吗?我们来一起分析一下。根据提议,我们可以画出如下所示的示意图,题目要求我们回答主机已发送给主机甲的确认序号是多少?我们从已知的第三个数据报文段首部中序号字段的值为 900 开始分析,这就表明其数据载荷的第一个字节的序号为900。由于数据载荷共有 500 个字节,因此数据载荷的最后一个字节的序号为1399。

16:15
根据第三个数据报文段,数据载荷的第一个字节的序号为900,可以得出第二个数据报文段。数据载荷的最后一个字节的序号为899。由于数据载荷共有 400 个字节,因此数据载荷的第一个字节的序号为500,相应的第二个数据报文段首部中序号字段的值应为500。

16:45
根据第二个数据报文段,数据载荷的第一个字节的序号为500,可以得出第一个数据报文段。数据载荷的最后一个字节的序号为499。由于数据载荷共有 300 个字节,因此数据载荷的第一个字节的序号为200,相应的第一个数据报文段首部中序号字段的值应为200。由于 TCP 规定只能对按序到达的最高序号进行确认,因此主机已发送的确认报文段实际上是对第一个数据报文段的确认。

17:27
由于第一个数据报文段数据载荷的最后一个字节的序号为499,因此针对该序号的确认序号应为500,表明序号 499 为止的全部数据已经收到了,现在希望接收 500 号及其后续数据。本节课到这里就结束了,我们将本节课的内容小结如下,同学们,我们下节课再见。

站内搜索

没有找到内容!