TCP建立连接的三次握手和释放连接的四次握手

TCP是面向连接的协议。运输连接时用来传送TCP报文的。TCP运输连接的建立和释放是每一次面向连接的通信中比不可少的过程。因此,运输连接就有三个阶段,即:连接建立,数据传送和连接释放。运输连接的管理就是使运输连接的建立和释放都能正常地进行。
在TCP连接建立过程中要解决一下三个问题:

  1. 要使每一方能够确知对方的存在
  2. 要允许双方协商一些参数(如最大窗口值,是否使用窗口扩大选项和时间戳选项以及服务质量等)
  3. 能够对运输实体资源(如缓存大小,连接表中的项目等)进行分配。

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


TCP的连接建立:
这里写图片描述

假设A运行的是TCP客户程序,而B运行TCP服务器程序。最初两端的TCP进程都处于CLOSED(关闭状态)。图中在主机下面的方框分别是TCP进程所处的状态。A主动打开连接,而B被动打开连接。

  • 一开始,B的TCP服务器进程先创建传输控制块TCB,准备接收客户进程的连接请求。然后服务器进程处于LISTEN(收听)状态,等待客户的连接请求。如有,即做出响应。
  • A的TCP客户进程也是首先创建传输控制块TCB。然后,在打算建立TCP连接时,向B发出连接请求报文段,这时首部中的同步为SYN = 1,同时选择一个初始序号 seq = x。TCP规定。SYN报文段(即SYN = 1的报文段)不能携带数据,但是要消耗掉一个序号,这时,TCP客户进程进入 SYN-SENT(同步已发送)状态。
  • B收到连接请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中应把SYN和ACK位置1,确认号时ack = x + 1,同时也为自己选择一个初始序号seq = y,请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。
  • TCP客户进程收到B的确认后,还要向B给出确认,确认报文段的ACK置1,确认号ack = y + 1,而自己的序号seq = x + 1.TCP的标准规定,ACK报文段可以携带数据。但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是seq = x + 1。这时,TCP连接已经建立,A进入ESTABLISHED(已经建立连接状态)。
  • 当B收到A的确认后,也进入ESTABLISHED状态。

上面给出的连接建立叫做三报文握手。在图中B发送给A的报文段,也可以拆分成两个报文段。可以先发送一个确认段报文段(ACK = 1, ack = x + 1),然后再发送一个同步报文段(SYN = 1, seq = y).这样的过程就变成了四报文握手,但效果是一样的。
为什么A最后还要发送一次确认呢?这主要是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。
所谓“已失效的连接请求报文段”是这样产生的,考虑一种正常情况,A发出连接请求,但因连接请求报文丢失而未收到确认。于是A再重传一次连接请求。后来收到确认,建立连接。数据传输完毕后,就释放了连接。A共发送了两个请求报文段,其中一个丢失,第二个到达B,没有“已失效的连接请求报文段”
现假定出现一种异常情况,即A发出的第一个连接请求报文段没有丢失,而是在某个网络节点长时间滞留了,以致延误到连接释放以后的某个时间才到达B。本来这时一个早已失效的报文段。但B收到此失效的连接请求报文段后,就误认为是A又发出一次新的连接请求。于是就向A发出确认报文段,同意连接。假定不采用报文握手,那么只要B发出确认,新的连接就建立了。
由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立,并一直等待A发来的数据,B的许多资源就这样白白浪费了。
采用三报文握手方法,可以防止上述现象的发生,例如在刚才的异常情况下,A不会向B的确认发出确认。B由于收不到确认,就知道A并没有要建立连接。


TCP的连接释放:
TCP连接释放过程比较复杂,我们仍结合双方状态的改变来阐明连接释放的过程。
数据传输结束后,通信的双方都可以释放连接。现在A和B都处于ESTABLISHED状态。A的应用进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。A把连接释放报文段首部的终止控制位FIN置1,其序号seq = u,它等于前面已经传送过的数据的最后一个字节的序号加1,这时A进入 FIN-WAIT-1(终止等待1)状态,等待B的确认。请注意,TCP规定,FIN报文段即使不携带数据,它也消耗掉一个序号。
这里写图片描述
B 收到连接释放报文段后即发出确认,确认号是ack = u + 1,而这个报文段自己的序号是v,等于B前面已经传送过的数据的最后一个字节的序号加1。然后B就进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程。因而从A到B这个方向的连接就释放了,这时的TCP处于半关闭(half-close)状态,即A已经没有数据要发送了,但B若发送数据,A仍要接收。也就是说,从B到A这个方向的连接并未关闭,这个状态可能会持续一段时间。
A收到来自B的确认后,就进入FIN-WAIT-2(终止等待状态2),等待B发出的连接释放报文段。
若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。这时B发出的连接释放报文段必须使FIN=1。现假定B的序号为w(在半关闭状态下B可能又发送一些数据)。B还必须重复上次已发送过的确认号ack = u + 1.这时B就进入LAST-ACK(最后确认状态),等待A的确认。
A在收到B的连接释放报文段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack = w + 1,而自己的序号是seq = u + 1(根据TCP标准,前面发送过的FIN报文段要消耗一个序号)。然后进入TIME-WAIT(时间等待状态),请注意,现在TCP连接还没有释放掉。必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,A才进入到CLOSED状态。时间MSL叫做最长报文寿命(Maximum Segment LifeTime),

猜你喜欢

转载自blog.csdn.net/lbb17745169396/article/details/80380519