TCP连接过程的“三次握手(Three-Way Handshake)”和“四次挥手(Four-Way Wavehand)”

最近在研究HTTP协议,对其中的三次握手和四次挥手做了详细地调研,整理如下:
TCP连接过程的“三次握手(Three-Way Handshake)”和“四次挥手(Four-Way Wavehand)”
首先,先来看一下OSI七层模型和TCP/IP四次模型对比图,可以发现TCP协议是对应第四层传输层的网络协议,下面分析其主要过程。
TCP连接过程的“三次握手(Three-Way Handshake)”和“四次挥手(Four-Way Wavehand)”
TCP三次握手(Three-Way Handshake)
TCP(Transmission Control Protocol)—传输控制协议,作用于第四传输层,是一种面向连接的、可靠的、基于字节流的传输层通信协议。主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。IP(Internet Protocol)—网际互联协议,作用于第三网络层,IP协议主要解决网络路由和寻址问题。
这里谈到的“三次握手”便是TCP连接建立的过程,这个连接必须是一方主动打开,一方被动打开。要明确三次握手不是TCP的要求,而是在不可靠信道上可靠地传输数据的必须要求。
第一次握手:Client向Server发送TCP报文(SYN(建连标识符)=1,seq(序号)=x)请求建连,并进入SYN-SENT状态,即告诉服务器请求建立连接;请求连接
第二次握手:Server收到Client的报文后,结束LISTEN状态,并返回一段TCP报文(SYN=1,ACK(确认序号有效标识符)=1,seq=y,ack(确认号)=x+1),随和Server进入SYN-RCVD状态,即告诉Client,Server收到了数据;同意连接
第三次握手:Client接收到来自Server的确认收到数据的TCP报文之后,明确了从Client到Server的数据传输是正常的,结束SYN-SENT状态,并返回最后一段TCP报文(ACK=1,seq=x+1,ack=y+1)。同样的,Server收到Client的返回报文之后,明确了从Server到Client的数据传输是正常,结束SYN-SENT阶段,进入ESTABLISHED阶段。确认同意连接
需要强调的是,第三次握手是为了防止已经失效的连接请求报文段突然又传到服务端产生错误,是十分必要的一个环节。

TCP四次挥手(Four-Way Wavehand)

TCP连接过程的“三次握手(Three-Way Handshake)”和“四次挥手(Four-Way Wavehand)”
“四次挥手”实际上是TCP连接的释放或者解除的过程。
第一次挥手:Client向Server发送TCP报文,请求释放连接,随后进入半关闭FIN-WAIT-1状态,Client停止向Server发送数据(非报文),但却能够接收Server传输的数据;
第二次挥手:Server接收到从Client发出的TCP报文之后,确认了Client想要释放连接,随后Server结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段ACK报文,表示“确认收到释放连接请求”;Client收到从Server发出的TCP报文之后,确Server收到了Client发出的释放连接请求,随后Client结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段;
第三次挥手:Server自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放Server到Client方向上的连接准备,再次向客户端发出一段TCP报文,随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。表示“已经准备好释放连接”;
第四次挥手:Client收到从Server发出的TCP报文,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向Server发送一段报文,表示“确认了Server已做好释放连接的准备”。随后Client开始在TIME-WAIT阶段等待2MSL,Server收到从Client发出的TCP报文之后结束LAST-ACK阶段,进入CLOSED阶段。由此正式确认关闭Server到Client方向上的连接。Client等待完2MSL之后,结束TIME-WAIT阶段,进入CLOSED阶段,由此完成“四次挥手”。

为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

四次挥手释放连接时,等待2MSL的意义?
MSL是Maximum Segment Lifetime的英文缩写,可译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

1.为了保证A发送的最有一个ACK报文段能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN和ACK 报文段的确认。B会超时重传这个FIN和ACK报文段,而A就能在2MSL时间内收到这个重传的ACK+FIN报文段。接着A重传一次确认。

2.防止已失效的连接请求报文段出现在本连接中,A在发送完最有一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。

参考博文:
https://blog.****.net/wnx_52055/article/details/88353441
https://blog.****.net/Yansky58685/article/details/98125046