剑指Offer(网络)——TCP协议的四次挥手原理详解

这里是TCP协议三次握手的笔记:https://blog.csdn.net/qq_41936805/article/details/103441134

所谓挥手,就是指的终止连接,TCP的四次挥手流程图如下:

这个行为,由客户端或者服务端任意一着触发close来触发,这里我们假设由客户端触发close

在这里插入图片描述

  1. 当数据传输完毕之后,双方才可以释放连接。

  2. 最开始的时候,客户端和服务端都处于Established状态,然后假设客户端主动关闭。

  3. 首先客户端发送连接释放报文,并且停止发送数据,在该数据报的报头中,携带的flag为FIN=1,sequence=u,这里的u,指的是刚才在连接状态下传送过来的最后一条信息的最后一个序号加上1,此时,客户端就进入了FIN_WAIT-1的状态,也就是第一次挥手

  4. TCP规定,即使FIN报文段不携带任何数据,也要消耗掉一个序号,让下一步回复报文的时候能够让sequence+1,那当我们的服务器收到了连接释放报文之后呢,也要发出确认报文,即ACK=1,ack=u+1,而自己的序列号sequence=v,此时服务端就进入了CLOSE-WAIT状态,这个时候,服务端处于半关闭状态,意味着客户端已经没有数据要发送了,但是服务端要是发送数据,客户端还是可以接受的,这种状态会持续到CLOSE-WAIT结束,也就是第二次挥手

  5. 此时,客户端就进入了FIN-WAIT-2的状态,等待服务器继续发送释放连接报文,也就是第三次挥手,并且要注意,这个时候服务器还是可以继续发送数据的,此时携带的flag为FIN=1,ACK=1,sequence=w,ack=u+1,当这条报文发送之后,就进入了LAST-ACK的状态,也就是服务端最终确认状态,等待客户端的最终确认

  6. 当客户端这个时候收到了服务端最后释放的报文之后,发送报文ACK=1,sequence=u+1,ack=w+1,之后进入TIME_WAIT状态,这时就是第四次挥手

  7. 等待2MSL(最长报文段寿命)之后,TCP Client就进入了关闭状态。之后当服务端接受到了客户端的报文之后,也会立刻进入到关闭状态

问题1:为什么会有TIME_WAIT状态?

  1. 确保有足够的时间让对方收到ACK,如果对方没有收到ACK,就会重传FIN,一来一回,正好是2MSL
  2. 防止这个连接和后面的连接混在一起,因为有些路由器会缓存报文数据包。

问题2:为什么需要四次挥手才能断开连接?

因为是全双工的,发送方和接收方都需要FIN报文和ACK报文,也就是说,这传递的过程,发送方和接收方都得各自发送两次,加在一起就是四次了。

问题3:服务器出现大量CLOSE_WAIT的原因?

当客户端发送过来一个FIN报文之后,服务端没有发送ACK,或者来确认FIN报文,说白了,就是对方关闭socket连接,我方忙于读或写,没有及时关闭连接。

一般这种情况都是程序中有bug,我们需要检查释放资源的代码

发布了296 篇原创文章 · 获赞 53 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_41936805/article/details/103443031