先记录一下TCP标志位,6种:
1、SYN (synchronous 建立联机)
2、ACK (acknowledgement 确认)
3、PSH (push 传送)
4、FIN (finish 结束)
5、RST (rest 重置)
6、URG (urgent 紧急)
seq (Sequence number 顺序号码), ack (Acknowledge number确认号码)
握手之前主动打开的主机A结束CLOSED阶段,被动打开的主机B也结束CLOSED阶段进入LISTEN阶段,随后开始“三次握手”
1、第一次握手: 主机A向主机B发送位码为SYN=1, 随机产生的顺序号码seq=x,主机A进入SYN-SENT阶段,主机B由SYN=1得知主机A要求建立联机;
2、第二次握手: 主机B接到请求后结束LISTEN阶段,确认联机信息,向主机A发送确认号码ack=x+1(主机A的seq+1),SYN=1,ACK=1,随机产生的顺序号码seq=y,主机B进入SYN-RCVD阶段;
3、第三次握手: 主机A收到主机B发送的确认信息后检查ack是否正确,是否为x+1,以及位码ACK是否为1,若正确,主机A再向主机B发送ack=y+1(主机B的seq+1),ACK=1,此时主机A进入established状态。主机B收到后确认ACK=1和seq=y+1之后也进入established状态,成功建立连接。
注意: 第三次握手的时候seq=x+1。原因为ack是向对方表示我期待收到的下一个序号,如你发送的ack=5,则表示你已收到序号到4的数据,下一个数据起点为5。TCP协议规定 SYN报文虽然不携带数据,但依旧需要消耗一个序号,所以第二三次握手的ack=x+1和ack=y+1,同时TCP标准规定 ACK报文段可以携带数据,但是如果不携带数据则不消耗序号,所以在这种情况下第三次握手时seq=x+1
四次挥手即TCP链接的释放,必须是一方主动释放,一方被动释放,图例为主机A主动释放
1、第一次挥手: 主机A向主机B发送FIN=1(标记位FIN表示请求释放链接),seq=m,随后主机A进入FIN-WAIT-1阶段,即半关闭阶段。停止主机A到主机B方向上发送数据(停止的是正常传输的数据,不是确认报文,确认报文依旧可发),但主机A依旧能接收主机B发送过来的数据,
2、第二次挥手: 主机B收到主机A发过来的结束报文,确认主机A要释放连接,主机B结束ESTABLISHED状态,进入CLOSED-WAIT阶段(半关闭状态),并返回ACK=1(确认收到主机A的释放连接请求),seq=n,ack=m+1。此时主机A收到主机B发送过来的报文,确认主机B已收到自己的释放请求,结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段
3、第三次挥手: 主机B经过CLOSED-WAIT阶段后,做好了释放准备,再次向主机A发送一段TCP报文,FIN=1,ACK=1,seq=p,ack=m+1。FIN和ACK表示已准备好释放连接,此处ACK并不是确认收到主机B报文的确认报文;随后主机B结束CLOSED-WAIT阶段,进入LASK-ACK阶段,并停止向主机A发送数据,但仍能收到主机A发送过来的数据;
4、第4次挥手: 主机A收到主机B发送过来的报文,确认主机B已做好释放准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向主机B发送ACK=1,seq=m+1,ack=p+1;随后主机A在TIME-WAIT阶段等待2MSL。等待完2MSL之后主机A结束TIME-WAIT阶段,进入CLOSED阶段,由此完成四次挥手。
为了建立可靠的通信信道,让双方确认自己和对方的通信是正常的,防止已失效的链接请求报文段又发送到服务器引起错误
因为建立连接时被动方无需任何准备就可以结束CLOSED状态,可以直接返回SYN和ACK报文,开始建立连接,而释放连接时被动方在收到释放连接请求时并不能立即释放连接,可能还有必要的数据进行处理,所以先被动方先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接后才能返回FIN释放连接报文
为的是确认主机B是否收到主机A发出的ACK报文;
MSL:Maximum Segment Lifetime,指的是一段TCP报文在传输过程中的最大生命周期。2MSL是主机B发出的FIN报文和主机A发出的ACK确认报文所能保持有效的最大时长;
如果在1MSL内主机B没有收到主机A发送的ACK确认报文,主机B就会再次发送FIN报文。若主机A在2MSL内再次收到主机B的FIN报文,说明主机B没有收到主机A的ACK报文,主机A会再次发送ACK报文,计时器会重置,再次等待2MSL;如果在2MSL内主机A并没有再次收到主机B的FIN报文,说明主机B已经正常收到主机A发出的ACK报文,主机A则进入CLOSED阶段,完成四次挥手。