TCP三次握手、四次挥手
先了解一下TCP的特点
TCP的特点
- TCP是面向连接的
- TCP提供可靠的服务:数据无差错,不丢失,不重复,按序到达
- TCP面向字节流
- TCP是一对一的
TCP三次握手
TCP的标志位
了解TCP三次握手的过程之前,需要先了解TCP的关键标志位
- SYN,简写为S,同步标志位,用于建立会话请求,同步序列号;
- ACK,简写为.,确认标志位,确认已接受的数据包;
- FIN,简写为F,完成标志位,表示传输完毕,将要关闭连接
若SYN=1,ACK=0,表示是来自发送方的一个“连接请求”;
若SYN=1,ACK=1,表示接收方“同意接受连接请求”。
TCP三次握手图解
TCP三次握手说明
第一次握手:客户端主动打开连接,将TCP报文标志位SYN置为1,并随机产生一个序号值seq=x(SYN=1,ACK=0,seq=x,请求连接),发送数据包给服务端。发送完毕进入SYN-SENT状态;
第二次握手:服务端接收到标志位为SYN=1,ACK=0的数据包,得知客户端请求建立连接。服务端将标志位置作:SYN=1,ACK=1,ack=x+1,并随机产生序号值seq=y;发送数据包给客户端,同意建立连接。进入SYN-RCVD状态。
第三次握手:客户端得到了服务端的确认。检查ACK是否为1,ack是否为x+1。若是的话,则ACK=1,ack=y+1。服务端再检查,ACK是否为1,ack是否为y+1。若正确则建立好连接通道。
为什么要三次握手
如果不要第三次握手:只要A发出请求,B接受请求,就建立连接。
为什么要第三次握手?
举个例子:
客户端A发出的第一次连接请求报文,由于某种原因,长时间滞留。一直到客户端A发出第二个连接请求后到达,那么服务端B则会认为A又发出了一次连接请求,于是接受A的第一次连接请求并确认连接。因为只通过前两次握手就可以建立连接。然而,B一直在等待A发送数据,A实际上并不发送数据了,这就造成了B的资源浪费。
如果有第三次握手:
A向B发送连接请求,B确认连接,还需要A的再次确认,才可以建立连接。上面的例子中,如果有第三次握手,那么B得不到A建立本次连接的再次确认,就不会建立连接。这次连接请求就失效了。
TCP四次挥手
TCP四次挥手图解:
TCP四次挥手说明
TCP连接的释放需要四次挥手,上图例子是客户端主动要求释放连接,服务器端被动接受释放连接。
第一次挥手: 客户端想释放连接。使FIN=1,表示请求释放连接,随机产生seq=x;发送给客户端,并进入FIN-WAIT-1阶段(半关闭状态,停止客户端向服务器端上发送数据)。但实际上,客户端还能向服务器端发送ACK确认报文。
第二次挥手: 服务器端接收到客户端想释放连接的请求。使ACK=1,ack=x+1,并随机产生seq=y。发送给客户端,表示“接收到了客户端的想释放连接的请求”。服务器端进入CLOSE-WAIT阶段。
客户端接收到报文,进入FIN-WAIT-2阶段。
前两次握手:客户端让服务器端知道:我想释放连接;服务器端让客户端知道:我知道了你想释放连接。于是可以确认关闭客户端到服务器端的连接,完成了一个方向上连接的释放!
第三次挥手: 在第二次挥手发送报文给客户端时,服务器端进入了CLOSE-WAIT阶段。当CLOSE-WAIT结束后, 服务器端做好了释放“服务器端到客户端方向”连接的准备。于是发送报文,使FIN=1,ACK=1,表示准备好释放连接。ack=x+1,seq=z;随后,服务器端进入LAST-ACK阶段。停止服务器端到客户端发送数据,但能接受来自客户端的数据。
第四次挥手: 客户端发送报文:ACK=1表示接收到了“服务器准备好释放连接".ack=z+1,seq=w;。
为什么要四次挥手
因为TCP是全双工模式,两个方向都可以进行通信,所以需要四次挥手来关闭两个方向上的连接。
TIME-WAIT阶段要等待2MSL
2MSL: 是报文段的最大生存时间,是报文段被丢弃前存在于网络的最长时间。
为什么要等待2MSL?
- 保证TCP全双工连接能够可靠关闭;
可能由于网络原因,服务器端没有收到客户端第四次挥手的ACK确认报文。那么服务器端就在超时之后重新发送FIN(重新来第三次挥手)。如果不等待2MSL,客户端直接进入CLOSED阶段,那么客户端就接收不到重新发送的FIN。导致没法完成全双工连接的释放。故必须等待2MSL,保证若有重新发送FIN,能够接收到FIN信号,并给予回应,从而完成全双工连接的关闭。 - 保证本次连接的数据在网络中消失
若客户端直接进入CLOSED阶段,即不等待本次连接的报文段数据消失就直接进入CLOSED阶段。那么如果,客户端发起新的连接,有可能上次连接的遗留数据参杂在新连接中,导致新连接接收到了脏数据。故必须等待2MSL,保证本次连接的数据在网络中丢弃,避免下次连接得到脏数据。