Tcp连接的建立与终止及其拥塞控制

TCP的连接建立主要有三次握手,终止有四次握手。看下图:

Tcp连接的建立与终止及其拥塞控制

前三个是建立连接的过程,简称三次握手,介绍一下其过程:

1,客户端发送一个带序号(即ISN,图中为1415531521)的SYN段请求tcp连接,即上面的报文段1

2,服务器发回一个带序号(即1823083521)的SYN段回应请求,同时将发来的客户端的ISN加1(即1415531522)以对客户端的SYN报文段进行确认

3,客户端将服务器端的ISN加1(即1823083521)以对服务器的SYN段进行回应。

简单的说就是

客户端说:“我要跟你连接...”

服务器端说:“好,可以”

客户端还说了一句保证的话:“那行,我们连接上了。”

连接终止是差不多的过程,不过是客户端和服务器端都需要主动发起一次连接终止的请求,然后等待对方确认。


TCP的拥塞控制主要有四个阶段,其中有两个重要的参数cwnd(拥塞窗口)和ssthresh(慢启动域值),四个阶段的目的都是通过改变这两个参数来控制数据的发送数量:

先看一张从别人那里引用的图,对照理解:

Tcp连接的建立与终止及其拥塞控制

1:慢启动,慢启动的过程是先发1个报文段过去,接收端正常接收后就开始发送2个,然后是4个......呈指数增长的发送,这样直到达到ssthresh设定的值便开始换一种方式增长发送报文段的数量,而不是指数增长。慢启动的原因是如果一开始就发送大量的数据包过去,可能会导致网络发生拥塞,因为新建的tcp连接一开始并不知道网络的利用情况。在一开始,先初始化cwnd为1个报文段,ssthresh为16个报文段,这样慢启动根据cwnd=1的值,先发送1个报文段,收到正确的ack回复后,cwnd要加上刚才发送的报文段数量,即加1,此时cwnd=2;之后发送端再发送2个报文段,cwnd再加2,即等于4;直到cwnd=ssthresh=16的时候,就开始进入另一种方式增长cwnd,即拥塞避免方式。

2:拥塞避免,在上面的慢启动到达cwnd=ssthresh=16之后,便进入了这一阶段的拥塞避免阶段,拥塞避免不是以上面的指数方式增长cwnd,而是以线性增长,每次收到ack确认后只增加1/cwnd个数据包。这样在一个往返时间内最多为cwnd增加1个报文段。在cwnd=24的时候,假如发生了超时,则会重置ssthresh=当前cwnd/2=12,而cwnd重置为1.这样重新进入慢启动的过程。

在上面发现了一个不好的地方,假如一个报文段丢失,但网络并没有拥塞,这样就会超时,然后又进入慢启动阶段,这回浪费很多的网络资源。所以便有了快速重传和快速恢复算法。首先要了解一个重复的ACK是怎么产生的,有两种产生方式,一种是丢失的报文引起接收方产生重复的ACK,另一种是报文被重新排序会产生重复的ACK,但是由于重新排序的报文段在产生一个新的ACK之前,只可能产生1~2个重复的ACK,所以如果连续收到3个或者3个以上重复的ACK,便很有可能是报文段丢失了,这样如果任发送发等待便会超时而进入慢启动过程,然而由于接收方只有在收到另一个报文段时才会产生重复的ACK,而该报文段已经离开网络并进入了接收方的缓存,也就是说收发两端并没有发生拥塞,所以我们并不想任其超时进入慢启动阶段,所以有了快速重传和快速恢复算法

3:快速重传和快速恢复算法,

1)当收到第3个重复的ACK时,进入快速重传阶段,将ssthresh设置为当前拥塞窗口cwnd的一半。重传丢失的报文段。设置cwnd为ssthresh加上3倍的报文段 大小。
2) 每次收到另一个重复的ACK时,cwnd增加1个报文段大小并发送 1个分组(如果新的cwnd允许发送)。
3) 当下一个确认新数据的ACK到达时,设置cwnd为ssthresh(在第1步中设置的值)。这个ACK应该是在进行重传后的一个往返时间内对步骤 1中重传的确 认。另外,这个ACK也应该是对丢失的分组和收到的第1个重复的ACK之间的所有中间报文段的确认。这一步采用的是拥塞避免,因为当分组丢失时我们将当 前的速率减半。

下面这张图说明了快速重传和快速恢复后的cwnd和ssthresh变化的情况:

Tcp连接的建立与终止及其拥塞控制

上面的图来自《tcp/ip详解,卷一》一书239页,书中有一讲解拥塞避免的列子,详细讲解了cwnd和ssthresh值的变化。



参考:《tcp/ip详解,卷一》