【前言】上一篇文章介绍了关于TCP的基础知识,以及建立(释放)连接和滑动窗口的概念。
本篇文章将延续上一篇的思路,继续介绍TCP实现可靠传输的机制。
上一篇文章里介绍过TCP采用停止等待协议,即在收到接收方的确认信息后才继续发送下面的数据。
那么如果(在一段时间内)发送方没有收到确认信息,我们便可以认为数据在传输的过程中出了差错,没有顺利传送到接收方。这种情况下,就需要一个“超时重传”的机制了。
TCP 每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到但还没有收到确认,就要重传这一报文段。
那么如何确定重传时间呢?这是TCP最复杂的问题之一。
如果把超时重传时间设置得太短,就会引起很多报文段的不必要的重传,使网络负荷增大。
但若把超时重传时间设置得过长,则又使网络的空闲时间增大,降低了传输效率。
为了得到较为合理的重传时间,TCP 采用了一种自适应算法。
该算法中最关键的就是往返时间(RTT)的测量。
测量往返时间时,由于有的报文经过重传后,无法判断收到的确认报文是重传报文的确认报文还是原报文的确认报文,故采用了Karn算法:
在计算平均往返时间 RTT 时,只要报文段重传了,就不采用其往返时间样本。
报文段每重传一次,就把 RTO 增大一些,以弥补重传时间的无法更新。
拥塞控制在研究拥塞控制的机制前,我们首先需要对“拥塞”的概念有所了解。
拥塞控制的基本概念 什么是“拥塞”在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种现象称为拥塞 (congestion)。
若网络中有许多资源同时产生拥塞,网络的性能就要明显变坏,整个网络的吞吐量将随输入负荷的增大而下降。
拥塞控制就是防止过多的数据注入到网络中,使网络中的路由器或链路不致过载;而流量控制往往指点对点通信量的控制,是个端到端的问题(接收端控制发送端)。
拥塞控制是一个全局性的过程,涉及到所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。
流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。
TCP采用基于窗口的方法进行拥塞控制。
TCP发送方维持一个“拥塞窗口”(congestion window),以控制端到端之间未确认的报文数量(拥塞的程度)。
这和之前提到的用于流量控制的“滑动窗口”很像,但是和由接受方决定的“滑动窗口”大小不同,“拥塞窗口”的大小是由发送方决定的。
发送窗口大小不仅取决于接收方公告的接收窗口,还取决于网络的拥塞状况。
真正的发送窗口值为:Min(公告窗口值,拥塞窗口值)
1、重传定时器超时
由于因传输出差错而丢弃分组的概率是很小的(远小于1%),所以只要出现了超时,就可以猜想网络可能出现了拥塞。
2、收到三个相同的ACK(3 duplicate ACKs)
先假设这么一种情况,B等待A发送首字节序号为3的报文段,给A发送“ack = 3”的确认报文段(ACK),而A在发送过程中出现了丢失,B收到的只有4、5字节的报文段;
此时B给A发送的确认报文中ack字段仍然等于3(因为字节3还没收到);
接着,在B收到字节6后,给A发送的确认报文仍然是“ack = 3”
这就是“收到三个相同ACK”的场景。
因此我们知道,“收到三个相同的ACK”说明有个别报文段在网络中丢失了,预示着网络状况不好,可能会出现拥塞,需要采取措施避免拥塞。
拥塞控制算法拥塞控制是个麻烦事儿,相关的算法也不少。或者说,多到让人有些头大。
不过不用担心,我们这里只介绍在RFC 5681文件中定义的四种互相紧密关联的算法:
慢开始(Slow Start)
拥塞避免(Congestion Aviudance)
快重传(Fast Reyransmit)
快恢复(Fast Recovery)