四次挥手介绍
首先可以发现,数据传输结束后,客户端A和服务端B都处于ESTABLISHED状态,通信的双方都可以释放连接,也可以同时关闭连接,但是较为常见的一种情况是由客户端发起关闭请求。 第一次挥手:图中客户端A第一次挥手,发送一个长度为1的报文给服务端,里面的关键位FIN置为1,代表结束终止的意思,请求释放连接,并且起始字节序号seq为u,注意这里的seq和服务器端的seq并不一样。并且A由ESTABLISHED状态进入FIN-WAIT-1(终止状态1)。 第二次挥手:服务器B收到A的请求关闭报文之后,做出反应,确认收到了来自A的请求关闭报文,所以这里的ACK确认为1,相应的确认号u+1生效,并且本身的起始字节序号seq为v,B由ESTABLISHED状态进入CLOSE-WAIT(等待关闭)状态,A收到了来自B的确认报文后由FIN-WAIT-1(终止状态1)变为FIN-WAIT-2(终止状态2)。并且这个时候TCP连接还是处于半关闭状态,也就是B可以给A发送数据,A要接收,但是A不能给B发送数据。 第三次挥手:上面也说到了第二次挥手后TCP还是处于半关闭状态,所以等服务端B确认了没有数据再发送了,就进行第三次挥手,里面的关键字段FIN=1代表请求释放连接,ACK=1且ack=u+1代表回应收到的第一次挥手中客户端发来的起始字节序号。并且本机的起始字节序号为w,而不是v+1,因为第二次挥手到第三次挥手期间服务端B有可能给A发送了消息,已经用掉了一部分字节序号,所以这里就断开了,如果中途没有发送数据的话w=v+1,因为每次报文都是1字节的长度。然后B由CLOSE-WAIT(等待关闭)状态变为了LAST-ACK状态。客户端在收到B的第三次挥手的报文时,状态由FIN-WAIT-2(终止状态2)变为TIME-WAIT(时间等待状态)。 第四次挥手:客户端A在收到第三次挥手的报文时,就立马给服务端B发送了第四次挥手的报文,内容其实是和第二次挥手一样的,确认收到了报文,并且给出了相应正确的确认号,本机的一个报文的起始字节序列号。然后服务端B收到了第四次挥手的报文,就进入了关闭状态,客户端A在等待2MSL之后,也进入了关闭状态。
为什么第四次挥手后客户端还要等待2MSL的时间才释放连接
2MSL是报文段最长寿命时长的2倍,即报文段在TCP连接中可以存活的最长时间。 MSL(Maximum Segment Life最长报文段寿命) 一个确认报文(第四次挥手)+一个请求报文(第三次挥手)
解释: 客户端发送出ACK=1报文后,开始维护2MSL计时器,假设客户端最后发送ACK=1确认收到服务器关闭连接的报文,在网络中滞留没有到达服务器,服务器在一段时间没有收到客户端的ACK=1回复,会重发第三次挥手的连接释放报文。客户端接到此报文,重置2MSL计时器,再次向服务器发送ACK=1报文,如果直到2MSL计时器到时间都没有收到服务器重发的连接释放报文,则客户端释放TCP连接
如果此时客户端已经释放了TCP连接,没有等待2MSL的时间,则不能接到服务器重发的连接释放报文,重发的报文找不到对应的连接,如果再向服务器发送TCP连接请求,此时无法保证两次连接的端口号不同,则可能出现这样的问题:前一次的连接某些数据滞留在网络中,这些延迟数据在建立新连接后到达客户t端,由于新老连接的端口号和IP都一样,TCP协议就认为延迟数据是属于新连接的,新连接就会接收到脏数据,这样就会导致数据包混乱。
为什么要四次挥手,三次挥手不行吗?
因为TCP连接是全双工通信,即客户端、服务器都可以收发数据,则在断开连接时,需要服务器和客户端都确定对方不再发送数据。 解释: 第一次挥手,客户端向服务器发送,服务器得知客户端将不再发送数据 第二次挥手,服务器向客户端发送,客户端得知服务器已经知道客户端不再发送数据 第三次挥手,服务器向客户端发送,客户端得知服务器将不再发送数据 第四次挥手,客户端向服务器发送,服务器得知客户端已经知道服务器不再发送数据 第一、二次挥手时,服务器可能还在向客户端发送数据,所以第二次挥手和第三次挥手不能合并。
如果已经建立连接,但客户端出现故障了怎么办?
采用心跳机制保活 解释:服务器维护一个计时器,每次服务器接到客户端的请求,都会重新复位计时器,如果超过一定时间没有接收到客户端的数据,服务器会向客户端发送一个探测报文,每隔一定时间发送一次,若连续发送一定数量的探测报文没有回应的话,服务器就认为客户端出了故障,关闭连接。
参考博客:https://blog.csdn.net/qq_37348221/article/details/114572978 参考书籍:《计算机网络(第七版)》谢希仁
|