一、四次握手的过程
TCP需要三次握手才能建立连接,整个过程如下图所示:
假设A运行的是TCP客户端进程,而B运行的是TCP服务端进程。最开始的时候两端的TCP进程都处于ESTABLISHED(已建立连接)状态。
这时候,A主动关闭,请求释放连接。
(1)第一次握手 A→ B
A的TCP客户进程向B发出释放连接请求报文段,其中FIN(终止位)=1,seq(序号)=u。
TCP规定,当报文段的FIN=1时,表明此报文段的发送方的数据已发生完毕,并要求释放连接;FIN报文段(FIN=1的报文段)不能携带数据,但是要消耗掉一个序号。
在A发送完毕之后,A的TCP客户端进程进入FIN-WAIT-1(终止等待1)状态。
(2)第二次握手 B→A
B在收到连接释放连接请求报文段之后,随即向A发送确认报文段。其中ACK=1,seq=v,ack(确认号)=u+1。
在B发送完毕之后,B的TCP服务端进程进入CLOSE-WAIT(关闭等待)状态。
TCP服务器进程这时应该通知高层应用经常,从A到B这个方向的连接就要释放了,这时的TCP连接处于半关闭(half-close)状态。
A在收到B的确认报文段之后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
(3)第三次握手 B→A
若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。B向A发出释放连接报文段,其中FIN=1,ACK=1,seq=w,ack=u+1。
TCP规定,当报文段的FIN=1时,表明此报文段的发送方的数据已发生完毕,并要求释放连接;FIN报文段(FIN=1的报文段)不能携带数据,但是要消耗掉一个序号。
在B发送完毕之后,B的TCP服务端进程进入LAST-ACK(最后确认)状态。
(4)第四次握手 A→BA在接收到B的释放连接请求报文段之后,必须对此发出确认。其中ACK=1,seq=u+1,ack=w+1。
A在发送完毕之后,进入到TIME-WAIT(时间等待)状态。B在接收到A的确认之后,进入到CLOSED(关闭)状态。
在经过时间等待计时器设置的时间2MSL之后,A才进入到CLOSED状态。
以上就是所说的四次握手过程。
二、四次握手的原因
四次握手可以看成是两个二次握手,分别是A的TCP客户端进程请求释放连接和B的TCP服务端进程请求释放连接。
为什么A在发送最后一次确认报文段之后还需要等待2MSL时间呢?主要有两个原因,一是为了让B能够按照正常步骤进入CLOSED状态,二是为了防止已失效的请求连接报文段出现在下次连接中,因而产生错误。
原因如下:
第一,为了保证A发送的最后一个ACK报文段能够到达B。因为这个ACK报文段有可能丢失,这样B就无法接收到而进入CLOSED状态。于是B会重传请求释放连接的报文段,A在这段等待时间接收到了,重传ACK报文段,这样B还是会顺利接收到确认报文段,进入CLOSED状态。如果此时A已经关闭了,那么就无法收到B的请求报文段,也不会发送ACK报文段,这样B就无法进入CLOSED状态了。
第二,在这2MSL的等待时间内,本次连接的所有报文都已经从网络中消失,从而不会出现失效的报文出现在下次连接中。
参考资料:
1、TCP协议中的三次握手和四次挥手(图解) http://blog.csdn.net/whuslei/article/details/6667471
2、简析TCP的三次握手与四次分手 http://www.jellythink.com/archives/705
3、TCP三次握手详解及释放连接过程 http://blog.csdn.net/oney139/article/details/8103223