笔记分享:网络基础之TCP/IP四次挥手

图片来源自网络

“挥手”是为了终止连接,TCP四次挥手的流程图如下:

  • 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态;
    • 客户端发送报文,完成信号FIN=1,序号seq=u
    • 进入完成FIN_WAIT_1状态,等待服务端确认
  • 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态
    • 服务端发送确认报文,确认信号ACK=1,序号=v,确认序号ack=u+1
    • 此时服务端就进入Close-wait状态,半关闭状态
    • 此时客户端就进入FIN-wait状态,终止等待状态,等待服务器发送释放连接报文
    • 这里有可能服务端还会持续完成数据传送。因此seq值会改变
  • 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
    • 服务端发送数据完成报文,完成信号FIN=1,确认信号ACK=1,序号seq=w,确认信号ack=u+1
    • 此时服务端进入最后确认状态,等待客户端发送确认
  • 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
    • 客户端确认报文,确认信号ACK=1,序号seq = u+1,确认序号ack=w+1
    • 此时服务端进入关闭状态
    • 此时客户端进入TIME-WAIT状态,时间等待状态,还未释放连接,必须经过2*MSL的时间才会进行释放。RFC定义为两分钟,而Linux的时间为30秒
  • 为什么会有TIME_WAIT状态
    • 确保有足够时间让对方(上图为server端)收到ACK包
    • 避免新旧连接混绕
  • 为什么需要四次握手才能断开连接
    • 因为全双工,发送方和接收方都需要FIN报文和ACK报文
  • 服务器出现大量CLOSE_WAIT状态的原因
    • 对方关闭socker连接,我方忙于读或写,没有及时关闭连接
    • 检查代码,特别是释放资源的代码
    • 检查配置,特别是处理请求的线程配置
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章