TCP可靠传输详解(拥塞控制+流量控制)

TCP可靠传输详解

标签(空格分隔): 计算机网络


可靠传输的要求

  1. 传输信道不产生差错
  2. 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据.

这里有两层意思,一是能够正确地传输数据,二是接收方能够及时处理发送方发送的数据。

可靠传输的工作原理

TCP为了提供可靠传输:

(1)首先,采用三次握手来建立TCP连接四次握手来释放TCP连接,从而保证建立的传输信道是可靠的。

(2)其次,TCP采用了连续ARQ协议(回退N,Go-back-N;超时自动重传)来保证数据传输的正确性,使用滑动窗口协议保证接方能够及时处理所接收到的数据,进行流量控制

(3)最后,TCP使用慢开始、拥塞避免、快重传和快恢复来进行拥塞控制,避免网络拥塞。

可靠传输实现过程

一、3次握手建立连接TCP连接

TCP连接的建立采用客户端服务器方式。主动发起连接建立的应用程序叫做客户,而被动等待连接建立的应用进程叫做服务器

TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP报文段。

TCP可靠传输详解(拥塞控制+流量控制)

如上图所示,本例中 A主动打开连接,而B被动打开连接。

  1. (一握手)一开始,B的TCP服务器进程先创建传输控制块TCB,准备接受客户进程的连接请求。然后服务器进程就处于LISTEN状态,等待客户的连接请求。如有,即做出响应。 A的TCP客户端进程首先创建控制传输块TCB**,然后在打算建立TCP连接时候,向B发出 连接请求报文段,这时首部中的同步位SYN = 1,同时选择一个初始化序号seq = X。TCP规定,任何SYN报文段(即SYN = 1的报文段)不能携带数据,但要消耗掉一个序号。
    此时TCP客户端进程进入SYN-SENT(同步已发送)状态
  2. (二握手) B收到连接请求报文段之后,如果同意建立连接,则向A发送确认。在确认报文段中SYN = 1且ACK = 1,确认号ack = x + 1。 同时也为自己选择一个初始化序号seq = y;同上,这个报文段也不能携带数据,但同样要消耗掉一个序号。这时TCP服务器进程进入了SYN-RCVD(同步收到)状态。(这里服务器发送给客户端的报文也可以拆分成两个报文段:一个确认报文段(ACK = 1,ack = x + 1)和一个同步报文段(SYN = 1,seq = y))
    3.***(三握手)*** TCP客户端进程收到B的确认后,还要向B给出确认,确认报文段的ACK = 1,确认号ack = y +1,自己的序号seq = 发过来的确认号 = x+1。TCP的标准规定,ACK报文段可以携带数据。但如果不携带数据则不消耗序号,这个情况下,下一个数据报文段的序号仍然是seq = x+1。 这时候,TCP连接已经建立,A进入了ESTABLISHED(已建立连接)状态,当B收到了A的确认后,也进入ESTABLISHED状态。
第一次握手: 客户端发送,服务端接收,此时服务端知道客户端的发送能力和自己的接收能力没问题
第二次握手: 服务端发送,客户端接受,此时客户端知道服务端的发送和接受能力没问题,自己的发送和接收能力没问题
第三次握手: 客户端发送,服务端接收,此时服务端知道客户端的发送和接收能力没问题,自己的发送和接收能力没问题

关于第三次为什么还要再发送一次确认报文段,书上说的是----为了防止A的已经失效的连接请求报文段在连接释放后又被传送到了B,在没有第三次握手的情况下,B接收到了A的请求报文段,并且向A发送确认报文后直接建立连接导致资源浪费,所以需要第三次A的主动握手来确认第一次握手是有效的.
如果A并没有发送,则对于B的第二次握手(确认同步报文段)并不会给予理睬,也不会对B的确认发出确认.B由于收不到确认,就知道A并没有要求建立连接.

二、4次挥手释放TCP连接

数据传输结束之后,通信的双方都可以释放连接.现在A和B都处于ESTABLISHED状态 如下图.

  1. (第一次挥手)A的应用进程先向其TCP发出连接释放报文段(FIN = 1,seq = u ),并停止在发送数据,主动关闭TCP连接。A把连接释放报文段首部的终止控制位FIN = 1,其序号 seq = u, u等于前面一传送过的数据的最后一个字节的序号加1.此时A进入 FIN-WAIT-1(终止等待1)状态,等待B的确认。请注意:TCP规定,FIN报文即使不携带数据,它也消耗掉一个序号。
  2. 第二次挥手)B收到连接释放报文段后即发出确认,确认号ack = u + 1,而这个报文段自己的序号 seq = v,等于B前面已传送过的数据的最后一个字节的序号加1.然后B就进入CLOSE-WAIT(等待关闭)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了。这时TCP连接处于半关闭状态,即A已经没有数据要发送了,但B如有数据要发送,A仍要接收。也就是说,从B到A这个方向上的的连接并未关闭,这个状态可能会持续一段时间
    A收到来自B的确认后就进入了FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
  3. 第三次挥手)若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。这时B发出的连接释放报文段就必须使FIN = 1。现假定B的序号为 W (在半关闭状态下B可能又发了一些数据使得序号seq从v到了w)。B还必须重复上次已经发送过的确认号ack = u + 1 。 此时B就进入了LAST-ACK(最后确认状态)等待A的确认。
  4. 第四次挥手) A在收到B的连接释放报文段后,必须对此发出确认。在确认报文段中 ACK = 1,确认号ack = w + 1;而自己的序号 seq = u + 1(根据TCP标准,前面发送过的FIN报文段需要消耗一个序号)。然后进入到TIME-WAIT(时间等待)状态。
    这时候TCP连接还没有释放掉,必须经过时间等待器(TIME-WAITER timer)设置的时间2MSL后,A才能进入到CLOSED状态。时间MSL叫做最长报文段寿命,默认建议设定为2分钟,也可根据实际情况设置更小的MSL值。
    因此,从A进入到TIME-WAIT状态后,需要经过2MSL才能进入到CLOSED状态,才能真正的释放连接。当A撤销相应的传输控制块TCB后,就结束了这次的TCP连接。

TCP可靠传输详解(拥塞控制+流量控制)

为什么A在TIME-WAIT状态下不许等待2MSL时间呢?

 1. 为了保证A发送的最后一个ACK报文能够到达B。如果B没有收到,则会重传自己的FIN+ACK报文段,A在2MSL时间内收到B的报文段,接着A重新确认一次,重新启动2MSL计时器。
 
 2. 为了防止 “三次握手”中出现的 “已经失效的连接请求报文段”。在A发送完最后一个ACK报文段后,在经过时间2MSL就可以让本连接持续的时间内所产生的所有报文段都从网络中消失,确保下一个新的连接不会出现旧连接的报文段。


除此以外,TCP还有一个**保活计时器**,能够确保在客户端出故障的时候,能够在一定时间内释放连接,节省资源。服务器每收到一次客户的数据,保活计时器就刷新一次,时间的设置通常是2个小时。若两个小时内没有收到客户的数据,服务器就发送一个探测报文段,以后每隔75秒发送一次。如果一连10次探测报文段发送后无客户的响应,服务器就认为这个客户端出现了故障,接着就关闭这个连接。

三、停止等待协议

全双工通信的双方既是发送方也是接收方,下面为了讨论方便仅考虑A作为发送方发送数据,而B作为接收方接受数据并发送确认。

停止等待是指每发送完一个分组就停止发送,等待对方的确认.在收到确认后再发送下一个分组.

超时重传
A只要过了一段时间仍然没有收到确认,就认为刚才发送的分组丢失了,因而重传前面发过的分组.

无差错情况

每发送一个分组,收到一个分组的确认,再发送下一个分组
TCP可靠传输详解(拥塞控制+流量控制)

出现差错

出现差错的两种情况:

  1. B收到M1,检测时出现了差错
  2. M1在传输过程中丢失了

对于第一种情况,B检测到M1错误后,就丢弃M1,其他什么也不做(也不发送数据通知A收到有差错的分组);
第二种情况,B没有收到M1,一直等待,不发送数据.

TCP可靠传输详解(拥塞控制+流量控制)

确认丢失

B收到M1后,发送的对M1的确认丢失了。A在设定的超时重传的时间内没有收到确认,重传M1。
B这时候又收到了M1,采取如下两步行动

  1. 丢弃这个重复分区
  2. 向A发送确认

TCP可靠传输详解(拥塞控制+流量控制)

确认迟到

B对M1的确认迟到了。此时A因为超时重传,重新传给B一份M1,B收到后丢弃同样的分组M1,并重传确认。
TCP可靠传输详解(拥塞控制+流量控制)

四、连续ARQ协议

由于停止等待ARQ协议信道利用率太低,所以需要使用连续ARQ协议来进行改善。这个协议会连续发送一组数据包,然后再等待这些数据包的ACK。
连续ARQ规定,发送方没收到一个确认,就把发送窗口向前滑动一个分组的位置。

发送窗口

发送窗口: 发送窗口内的分组可以连续发送出去而不需要等待对方的确认。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。

累计确认

累积确认:接收方不必对收到的分组逐个发送确认,而是在收到几个分组后,对按序到达的最后一个分组发送确认,这就表示:到发送确认的这个分组为止的所有的分组都已经正确收到了

Go-back-N(回退N)

Go-back-N(回退N):表示需要退回来重传已经发送过的N个分组。 如果发送方发送了5个分组,而第3个分组丢失了,这时候接收方只能对前2个分组发出确认。发送方在一定时间没有收到后面3个分组的确认信息后,只能把后面3个分组重传一次。

五、滑动窗口的具体实现

假定数据传输只在一个方向进行,即A发送数据,B给出确认

滑动窗口协议在在发送方和接收方之间各自维持一个滑动窗口,发送发是发送窗口,接收方是接收窗口,而且这个窗口是随着时间变化可以向前滑动的。它允许发送方发送多个分组而不需等待确认。TCP的滑动窗口是以字节为单位的。

如下图所示,发送窗口中有四个概念::已发送并收到确认的数据(不在发送窗口和发送缓冲区之内)、已发送但未收到确认的数据(位于发送窗口之内)、允许发送但尚未发送的数据(位于发送窗口之内)、发送窗口之外的缓冲区内暂时不允许发送的数据。

接收窗口中也有四个概念:已发送确认并交付主机的数据(不在接收窗口和接收缓冲区之内)、未按序收到的数据(位于接收窗口之内)、允许的数据(位于接收窗口之内)、不允许接收的数据(位于发送窗口之内)。

TCP可靠传输详解(拥塞控制+流量控制)

规则:

(1)凡是已经发送过的数据,在未收到确认之前,都必须暂时保留,以便在超时重传时使用。

(2)只有当发送方A收到了接收方的确认报文段时,发送方窗口才可以向前滑动几个序号。

(3)当发送方A发送的数据经过一段时间没有收到确认(由超时计时器控制),就要使用回退N步协议,回到最后接收到确认号的地方,重新发送这部分数据。

六、利用滑动窗口进行拥塞控制

流量控制: 就是让发送方的发送速率不要太快,要让接收方来得及接受

rwnd : receiver window 接收窗口大小.
发送方的发送窗口不能超过接收方给出的接收窗口的。

TCP可靠传输详解(拥塞控制+流量控制)

七、拥塞控制

拥塞
在某段时间,对网络中某一资源的需求超过了该资源所能提供的可以部分,网络性能就要变坏。
拥塞控制
防止过多的数据注入到网络中,这样可以使得网络中的路由器或或者链路不过载.也就是网络能够现在的网络负荷,这是一个全局性的过程
流量控制
点到点的通信量的控制,端到端的问题

发送方让自己的发送窗口等于拥塞窗口cwnd(congestion window)
发送方控制拥塞窗口的原则是: 只要网络没有出现拥塞,拥塞窗口就可以再大一些.
一旦出现了拥塞(确认报文没有按时收到)或者有可能出现拥塞,就必须把拥塞窗口缩小.

四种拥塞控制的算法:

  1. 慢开始
  2. 拥塞避免
  3. 快重传
  4. 快恢复

1.慢开始

思路
由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值.在每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个SMSS的数值。

每经过传输轮次,拥塞窗口cwnd就加倍。

2.拥塞避免

思路
让拥塞窗口缓慢的增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是像慢开始阶段成倍增加.

拥塞避免阶段,拥塞窗口按线性规律缓慢增长.

3.快重传

思路
当收到了失序的报文段时,立即发出对已收到报文段的重复确认,发送方只要一连收到3个重复确认,就知道对方没有收到报文段,因而立即进行重传.

TCP可靠传输详解(拥塞控制+流量控制)

4.快恢复

思路
门限值调整:ssthesh = cwnd/2 (即当前拥塞窗口的一半),同时设置拥塞窗口大小 = 门限值,并执行 拥塞避免算法。

如果出现了超时的状况而不是3-ACK,则需要将门限值调整为:ssthesh = cwnd/2 (即当前拥塞窗口的一半),同时设置当前拥塞窗口大小cwnd = 1,并使用慢开始算法。

拥塞控制总结

TCP可靠传输详解(拥塞控制+流量控制)