可靠传输的工作原理
引入
- TCP 发送的报文段是交给 IP 层传送的。但 IP 层只能提供尽最大努力服务,也就是说,TCP 下面的网络所提供的是不可靠的传输。因此,TCP 必须采用适当的措施才能使得 2 个运输层之间的通信变得可靠
- 理想的传输条件有以下两个特点(在这样的理想传输条件下,不需要采取任何措施就能够实现可靠传输)
- 传输信道不产生差错
- 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据
- 然而实际的网络都不具备以上两个理想条件。但我们可以使用一些可靠传输协议,在不可靠的传输信道实现可靠传输
- 当出现差错时,让发送方重传出现差错的数据
- 在接收方来不及处理收到的数据时,及时告诉发送方适当降低发送数据的速度
停止等待协议
"停止等待" 就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。在发送完一个分组后,必须暂时保留已发送的分组的副本,以备重发。
传输可能出现的情况
全双工通信的双方既是发送方也是接收方。为了讨论问题的方便,我们仅考虑 A 发送数据而 B 接收数据并发送确认。因此 A 叫做发送方,而 B 叫做接收方。
无差错
A 发送分组 M1,发完就暂停发送,等待 B 的确认 (ACK)。B 收到了 M1 向 A 发送 ACK。A 在收到了对 M1 的确认后,就再发送下一个分组 M2。
出现差错
- 在接收方 B 会出现两种情况:// 在这两种情况下,B 都不会发送任何信息
- B 接收 M1 时检测出了差错,就丢弃 M1,啥也不做(不通知 A 收到有差错的分组)
- M1 在传输过程中丢失了,这时 B 当然什么都不知道,也什么都不做
- 如何保证 B 正确收到了 M1 呢? [解决方法] 超时重传
- A 为每一个已发送的分组都设置了一个超时计时器
- A 只要在超时计时器到期之前收到了相应的确认,就撤销该超时计时器,继续发送下一个分组 M2
确认丢失/迟到
- 确认丢失
- B 所发送的 {对 M1 的确认} 丢失了,那么 A 在设定的超时重传时间内不能收到确认,但 A 并无法知道:是自己发送的分组出错、丢失了,还是 B 发送的确认丢失了。因此 A 在超时计时器到期后就要重传 M1
- 假定 B 又收到了重传的分组 M1;这时 B 应采取两个行动:① 丢弃这个重复的分组 M1,不向上层交付;② 向 A 发送确认
- 不能认为已经发送过确认就不再发送,因为 A 之所以重传 M1 就表示 A 没有收到对 M1 的确认
- 确认迟到
- 传输过程中没有出现差错,但 B {对分组 M1 的确认} 迟到了
- A 会收到重复的确认,对重复的确认的处理很简单:收下后就丢弃
- B 仍然会收到重复的 M1,同样要丢弃重复的 M1,并重传确认分组
超时重传时间
重传机制是 TCP 中最重要和最复杂的问题之一。
TCP 每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到但还没有收到确认,就要重传这一报文段。
- 如果把超时重传时间设置得太短,就会引起很多报文段的不必要的重传,使网络负荷增大。
- 但若把超时重传时间设置得过长,则又使网络的空闲时间增大,降低了传输效率。
- 超时计时器的重传时间的选择应当比 {数据在分组传输的平均往返时间} 更长一些。
TCP 采用了一种自适应算法,根据对端到端往返时延的连续测量,不断调整和设定重传定时器的超时重传时间。
自动重传请求 ARQ
- 通常 A 最终总是可以收到对所有发出的分组的确认。如果 A 不断重传分组但总是收不到确认,就说明通信线路太差,不能进行通信
- 使用上述的确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信
- 像上述的这种可靠传输协议常称为 自动重传请求 ARQ (Automatic Repeat reQuest);就是说,重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组
信道利用率
可以看出,当 {往返时间 RTT} 远大于 {分组发送时间 TD} 时,信道的利用率就会非常低。若出现重传,则对传送有用的数据信息来说,信道的利用率就还要降低。
引入 [流水线传输]
- 为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用 [流水线传输]。也就是从 "提高TD" 入手,提高信道利用率!
- 流水线传输就是发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认,这样可使信道上一直有数据不间断地传送。
- 当使用流水线传输时,就要使用下面介绍的 [连续ARQ协议] 和 [滑动窗口协议] 来实现可靠传输。
连续 ARQ 协议
发送方滑动窗口
a. 位于发送窗口内的分组都可连续发送出去,而不需要等待对方的确认(信道利用率提高了)。
b. 连续 ARQ 协议规定,发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置(窗口里的数据不能发完就删,得等确认消息过来,也就是分组不在窗口里面了,才能从缓存中删除)。
接收方累计确认
- 即不必对收到的分组逐个发送确认,而是对按序到达的最后一个分组发送确认。
- 这样就表示:到这个分组为止的所有分组都已正确收到了
- 采用的确认(ACK):期待序号为 N 的字节 , 表明已收到前 N-1 个字节数据
- 优点:容易实现,即使确认丢失也不必重传
- 如 {确认报文} 中序号为 6,则表明前 5 字节已经收到,期待 6 字节的数据
- 发送方发送窗口向前滑动到 6 的位置
- 发送方可将前 5 个分组的副本删除
- 缺点是不能向发送方反映出接收方已经正确收到的所有分组的信息 → Go-back-N(回退 N)
- 如果发送方发送了前 5 个分组,而中间的第 3 个分组丢失了。这时接收方只能对前两个分组发出确认(接收方期待第3个分组)
- 发送方无法知道后面 3 个分组的下落,而只好把后面的 3 个分组都再重传一次
- 这就叫做 Go-back-N(回退 N),表示需要再退回来重传已发送过的 N 个分组
可靠通信的具体实现
- TCP 连接的每一端都必须设有两个窗口:1 个发送窗口和 1 个接收窗口
- TCP 的可靠传输机制用 {字节的序号} 进行控制,TCP 所有的确认都是基于序号而不是基于报文段
- TCP 两端的 4 个窗口经常处于动态变化之中
- TCP 连接的往返时间 RTT 也不是固定不变的,需要使用特定的算法估算较为合理的重传时间