TCP的报文是交给IP层传送的,但是IP层只能提供尽最大努力交付的服务,也就是说,TCP下面的网络所提供的是不可靠传输,其实就是传输信道是不可靠的(所谓的信道,就是指连接信号发送方和接收方的传输线路,包括双绞铜线、同轴电缆、光纤、陆地无线电或者卫星无线电等物理媒体)这时,传输层的可靠传输机制就显得特别重要。
一、可靠传输的要求
所谓的可靠,就是能保证数据的正确性,无差错、不丢失、不重复、并且按序达到。
二、TCP可靠传输的机制原理
TCP首先采用三次握手来建立连接、四次挥手来释放连接。其次TCP采用了连续ARQ协议,即自动重传请求(Automatic Repeat-reQuest)来保证数据传输的正确性,使用滑动窗口协议来保证接收方能够及时处理接收到的数据,进行流量控制。最后TCP使用慢开始、拥塞避免、快重传、快恢复来进行拥塞控制,避免网络拥堵。下面我们将分别介绍三次握手、四次挥手、连续ARQ、拥塞控制。
1、tcp的三次握手的过程和必要性(这里假设A是client,B是server)
三次握手过程:
第一次握手:A发送SYN包(SYNC=j)到达B,并进入SYN_SEND状态,等待服务器B确认
第二次握手:B收到SYN包后,也会发送一个SYN包给A,这个包里面带有ACK=j+1用来确认A的SYN,和B自己的SYN=k,B进入SYN_RECV状态
第三次握手:A收到B的SYN+ACK包,向B发送确认包ACK(ACK=k+1),发送完毕,A和B进入ESTABLISHED状态,完成三次握手
三次握手的必要性:
假如只进行一次握手,客户端发送连接请求后,没有收到服务端的应答,是没法判断连接是否成功的。
假如只进行两次握手,客户端发送连接请求后,会等待服务器端的应答。但是会出现的问题是,假如客户端的SYN迟迟没有到达服务器端,此时客户端超时后,会重新发送一次连接,假如重发的这次服务器端收到了,且应答客户端了,连接建立了。但是建立后,第一个SYN也到达服务端了,这时服务端会认为这是一个新连接,会再给客户端发送一个ACK,这个ACK当然会被客户端丢弃。但是此时服务器端已经为这个连接分配资源了,而且服务器端会一直维持着这个资源,会造成浪费
三次握手,两次握手的问题在于服务器端不知道SYN的有效性,所以如果是三次握手,服务器端会等待客户端的第三次握手,如果第三次握手迟迟不来,服务器端就会释放相关资源。但是有人会问,假如第三次握手没有到达服务器端呢?但是这时客户端认为连接已经建立了。但是其实这种情况下,只要客户端向服务器端写数据,就会收到服务器端的RST应答,这时客户端就能知道出现问题了。
2、tcp的四次挥手过程和必要性(假设A是client B是server,且最开始都处于ESTABLISHED状态)
第一次挥手:A->B,A向B发出释放连接请求的报文,其中FIN(终止位) = 1,seq(序列号)=u;在A发送完之后,A的TCP客户端进入FIN-WAIT-1(终止等待1)状态。此时A还是可以进行收数据的
第二次挥手:B->A:B在收到A的连接释放请求后,随即向A发送确认报文。其中ACK=1,seq=v,ack(确认号) = u +1;在B发送完毕后,B的服务器端进入CLOSE_WAIT(关闭等待)状态。此时A收到这个确认后就进入FIN-WAIT-2(终止等待2)状态,等待B发出连接释放的请求。此时B还是可以发数据的
第三次挥手:B->A:当B已经没有要发送的数据时,B就会给A发送一个释放连接报文,其中FIN=1,ACK=1,seq=w,ack=u+1,在B发送完之后,B进入LAST-ACK(最后确认)状态。
第四次挥手:A->B;当A收到B的释放连接请求时,必须对此发出确认,其中ACK=1,seq=u+1,ack=w+1;A在发送完毕后,进入到TIME-WAIT (时间等待)状态。B在收到A的确认之后,进入到CLOSED(关闭)状态。在经过时间等待计时器设置的时间之后,A才会进入CLOSED状态。
四次挥手的原因:
其实是客户端和服务端的两次挥手,也就是客户端和服务端分别释放连接的过程。可以看到,客户端在发送完最后一次确认之后,还要等待2MSL的时间。主要有两个原因,一个是为了让B能够按照正常步骤进入CLOSED状态,二是为了防止已经失效的请求连接报文出现在下次连接中。
解释:
1)、由于客户端最后一个ACK可能会丢失,这样B就无法正常进入CLOSED状态。于是B会重传请求释放的报文,而此时A如果已经关闭了,那就收不到B的重传请求,就会导致B不能正常释放。而如果A还在等待时间内,就会收到B的重传,然后进行应答,这样B就可以进入CLOSED状态了。
2)、在这2MSL等待时间里面,本次连接的所有的报文都已经从网络中消失,从而不会出现在下次连接中。
3、连续ARQ协议
在介绍连续ARQ协议之前,我们要先说一下停止等待协议。停止等待协议的有点就是比较简单,好实现。基本原理是A发送一个分组,发送完就暂停发送,然后一直等待接收方B的应答。A在收到B的应答之后,再发送下一个分组。如果中途B发现包有错或者就没有收到包,那么也就不会向A发送应答包。此时A规定时间内要是没有等到应答包,就会重新传送刚才的分组,也就是所谓的超时重传。从这个过程也可以看出,假如A发送分组的时间为Ta,B发送确认的时间为Tb,往返时间为Tr,那么完整发送一个分组的时间为Ta+Tb+Tr。过了这个时间后,第二个分组才开始发送。这样子的信道利用率和传输效率就比较低了。这时就引入连续ARQ了。
从上面的图来看,图(a)是发送方维持的发送窗口,它的意义是:位于发送窗口内的5个分组都可以连续发送出去,而不需要等待对方的确认,这样就提高了信道利用率。
连续ARQ协议规定,发送方没法送一个确认,就把发送窗口向前滑动一个分组的位置。例如上面的图(b),当发送方收到第一个分组的确认,就把发送窗口向前移动一个分组的位置。如果已经发送了前5个分组,则现在可以发送窗口内的第6个分组。
接收方一般都是采用累积确认的方式。也就是说接收方不必对收到的分组逐个发送确认。而是在收到几个分组后,对按序到达的最后一个分组发送确认。如果收到了这个分组确认信息,则表示到这个分组为止的所有分组都已经正确接收到了。
累积确认的优点就不用多说了,缺点是,不能正确的反映收到的分组,比如发送方发送了前5个分组,而中间的第3个分组丢失了,这时候接收方只能对前2个发出确认。而不知道后面3个分组的下落,因此只能把后面的3个分组都重传一次,这种机制叫Go-back-N(回退N),表示需要再退回来重传已发送过的N个分组。
4、拥塞控制
1)TCP流量控制
拥塞控制就是防止过多的数据注入到网络中,这样可以使网路中的路由器或链路不致于过载。而流量控制往往是指点对点通信量的控制,是个端到端的问题。流量控制所要做的就是控制发送端发送速率,以便使接收端来得及接受。利用滑动窗口机制就可以实现流量的控制。原理就是运用TCP报文中的窗口大小字段来控制,发送的发送窗口不可以大于接收方的接收窗口大小。如果接收方没有足够的缓存来接收数据,发送方就会收到一个零窗口的通知。此时发送方停止发送。并且定时发送一个窗口探测报文来探测接收方的接收能力。
2)TCP拥塞控制
在某段时间内,若对网络中的某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变差,这种叫做拥塞。
拥塞控制就是防止过多的数据注入到网络中,这样可以使网路中的路由器或链路不致于过载。RFC2581定义了四种拥塞控制算法,即慢开始,拥塞避免、快重传、快恢复。
下图是慢启动和拥塞避免的一个可视化描述。我们以段为单位来显示cwnd和ssthresh,但它们实际上都是以字节为单位进行维护的。
拥塞窗口的概念:
发送报文段速率的确定,纪要根据接收端的能力,又要从全局考虑不要使网路发生拥塞,这由接收窗口和拥塞窗口两个状态量来决定。接收窗口又称通知窗口,是接收端根据目前接收缓存大小所许诺的最新窗口值,是来自接收端的流量控制。拥塞窗口cwnd是发送端根据自己估计的网络拥塞程度而设置的窗口值,是来自发送端的流量控制。
慢启动原理:
当主机开始发送数据时,如果立即将较大的发送窗口的全部数据注入网路中,那么由于不清楚网络的情况,有可能引起拥塞。比较好的方式是试探一下,即从小到大逐渐增大发送端的拥塞控制窗口数值。当窗口值逐渐增大时,为了防止cwind的增长导致网络拥塞,还需要一个变量--慢开始门限ssthresh
拥塞控制
具体过程为:
TCP连接初始化,将拥塞窗口设置为1。接下来执行慢开始算法,当cwind==ssthresh时,开始执行拥塞避免算法:cwnd按照现行规律增长。当网络发生拥塞时,吧ssthresh值更新为拥塞前ssthresh的一半,cwnd重新设置为1。重复执行上个步骤。
快重传和快恢复
一条TCP连接有时会因等待重传计时器的超时而空闲较长的时间,慢开始和拥塞避免无法很好的解决这类问题,因此提出了快重传和快恢复的拥塞控制方法。
快重传算法并非取消了重传机制,只是在某些情况下更早的重传丢失的报文段(如果当发送端接收到三个重复的确认ACK时,则断定分组丢失,立即重传丢失的报文段,而不必等待重传计时器超时)。
例如:M1,M2,M3 -----> M1,M3,缺失M2,则接收方向发送方持续发送M2重复确认,当发送方收到M2的三次重复确认,则认为M2报文丢失,启动快重传机制,重传数据,其他数据发送数据放入队列,待快重传结束后再正常传输。
快恢复算法有以下两个要点:
1)当发送方连续收到接收方发来的三个重复确认时,就执行“乘法减小”算法,把慢开始门限减半,这是为了预防网络发生拥塞。
2)由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法,而是把cwnd(拥塞窗口)值设置为慢开始门限减半后的值,然后开始执行拥塞避免算法,使拥塞窗口的线性增大。
5、参考资料:
1、https://blog.csdn.net/guoweimelon/article/details/50879302
2、TCP可靠传输&流量控制&拥塞控制 http://my.oschina.net/manmao/blog/601585