前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP四次挥手原理

TCP四次挥手原理

作者头像
全栈程序员站长
发布2022-09-05 10:37:15
2440
发布2022-09-05 10:37:15
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

我们对TCP三次握手耳熟能详,那么你知道TCP四次挥手过程吗?

一、前言

唐代诗人李商隐在《无题》诗中写到:“相见时难别亦难,东风无力百花残”,表达了自己与心爱之人相见之难、离别之苦。如果把这句诗用在形容TCP连接的建立与释放过程,也很贴切。我们知道TCP建立连接时需要三次握手,而TCP连接释放则需要四次挥手,是不是很像诗中描述的意境——见面很难,分开更难。 如果你还不清楚相见之难TCP三次握手过程,可以看我的上篇博文TCP三次握手原理,这样便于你更好理解TCP四次挥手释放连接的过程。

二、TCP四次挥手过程

TCP四次挥手指的是TCP连接释放过程, 不同于TCP连接建立时的三次握手过程,TCP连接释放过程更加复杂。在进入正题前,我们先回忆下TCP协议的两个重要特点:

  • TCP协议面向连接:应用在使用TCP协议通讯时,必须要先建立TCP连接。
  • TCP连接是双向通信:通信的两端是对等的,既能发送数据,也能接收数据,就向我们打电话时一样,既能说也能听。

这两个重要特点决定了TCP连接的释放过程。下面我们一起来看下TCP四次挥手的过程都发生了什么。为了更好的理解,简单的画了下TCP四次挥手示意图如下:

TCP四次挥手过程
TCP四次挥手过程

TCP连接数据传输结束后,通信的双方client与server都可以选择释放当前TCP连接,此时client与server都处于ESTABLISHED(连接确立)状态,TCP连接释放从此状态开始,我们假设是client的应用进程主动发起TCP连接释放:

  • 第一次挥手:client向server主动发送连接释放报文FIN=1,seq=u),报文的首部控制位FIN=1,代表自己的数据已经发送完毕,并且要求释放TCP连接。序号seq=u,u的值为client前面已传送数据的最后一个字节序号加1,client发送完后进入FIN-WAIT-1(终止等待1)状态。
  • 第二次挥手:server收到client的连接释放报文后即给出确认报文ACK=1,ack=u+1,seq=v),序号seq=v,值为server前面已传送数据的最后一个字节序号加1,然后server进入CLOSE-WAIT(关闭等待)状态。这时候client到server这个方向连接就释放了,TCP连接处于 半关闭(half-close)状态,client不再发送数据,但是server仍然可以发送数据给client。 client收到server确认后进入FIN-WAIT-2(终止等待2)状态,然后等待server发出连接释放报文
  • 第三次挥手:处于CLOSE-WAIT状态的server发送完所有数据后,主动释放连接,server发送的连接释放报文FIN=1,ACK=1,seq=W,ack=u+1),因为半关闭状态,server可能又发送了一些数据,所以序号的值为W,同时保持确认号ack=U+1与上次一致,发送完毕后,server进入LAST-ACK(最后确认)状态,等待client确认。
  • 第四次挥手:client收到server连接释放报文后,给出确认报文(ACK=1,ack=w+1,seq=u+1),此时连接还没释放掉,client要时间等待计时器设置的2MSL的时间,才最终进入CLOSED状态。时间MSL是最长报文寿命时长,RFC793建议为2分钟,但是现在网络中,这个时间设置更小。也就是说client要等待4分钟才能进入CLOSED状态,开始下一个连接。

上面就是TCP连接的释放过程,如果你觉得比较复杂可以简单理解为这样:

client server 数据传输完毕,请求释放连接! 收到,可以释放连接,等我会儿 我还有数据需要发 送,完毕后通知你 我的数据也发送完毕,可以释放连接 收到,释放连接!bye client server

三、小细节

1.为什么client在TIME-WAIT状态必须等待2MSL的时间?
  • 为了保证client的最后发送的ACK报文能到达server。因为这个ACK报文可能丢失,导致处于LAST-ACK状态的server收不到对自己释放连接报文的确认。若是server超时重传了这个报文,client就能在2MSL时间内收到,并且重新一次确认,并重启2MSL计时器。
  • 防止出现“已失效的连接请求报文段”出现,2MSL时间,可以使本连接持续时间内的报文段都从网络中消失。建立下一个TCP连接时就不会出现上次旧连接请求报文段
2.如果一方突然出故障了怎么办?

在TCP连接建立后,client与server传输过程中,假设client突然出故障了,server显然无法再收到client数据了,但是server不能白白等下去。这时TCP的保活计时器(keepalive timer)就登场了。server每收到一次client的数据,就重新设置一下计时器,时间通常是2小时,若2小时内没有再收到client数据,server就会发送一次探测报文段,以后每隔75分钟发送一次,若一连发送10次,client都没有任何响应,server会认为client故障了,直接关闭连接。

保活计时器
保活计时器

四、总结

为了更清晰看到TCP各种连接之间关系,最后附上一张TCP有限状态机图:

在这里插入图片描述
在这里插入图片描述

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/137336.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年6月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、TCP四次挥手过程
  • 三、小细节
    • 1.为什么client在TIME-WAIT状态必须等待2MSL的时间?
      • 2.如果一方突然出故障了怎么办?
      • 四、总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档