TCP四次挥手原理

TCP四次挥手原理TCP协议\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有限状态机图:
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • seekg()/seekp()与tellg()/tellp()的用法详解

    seekg()/seekp()与tellg()/tellp()的用法详解对输入流操作:seekg()与tellg()对输出流操作:seekp()与tellp()下面以输入流函数为例介绍用法:seekg()是对输入文件定位,它有两个参数:第一个参数是偏移量,第二个参数是基地址。对于第一个参数,可以是正负数值,正的表示向后偏移,负的表示向前偏移。而第二个参数可以是:ios::beg:表示输入流的开始位置ios::cur:表示输入流的当前位置io

  • 电商架构图_电商运营方案

    电商架构图_电商运营方案电商架构图

  • js通过contentWindow控制iframe子页面元素点击事件,并把值传给父页面[通俗易懂]

    js通过contentWindow控制iframe子页面元素点击事件,并把值传给父页面[通俗易懂]本来需要点击一个图片后,显示一个iframe上传框.点击上传,从而操作子页面中的点击上传动作,再把值传给父页面.或控制父页面中iframe元素的显示状态.不过.通过upload()函数,可以不用显示上传框了,直接激活子页面中的上传动作.另外,onchange事件则可以自动提交上传,不必用户点击上传按钮了.三步并做一步<!–父页面中的上传按钮–><imgsrc="…

    2022年10月19日
  • linux安装anaconda及配置pytorch环境

    文章目录下载anaconda使用conda创建新环境判断是否安装成功判断pytorch是否安装成功检验是否可以使用GPU下载anaconda这里有多种方法,可以下载到windows然后通过xftp传到linux服务器上,也可以使用wget命令直接在linux上下载我这里使用的是第二种方法,下载源使用的是官网的官网,如果觉得速度太慢可以使用清华镜像源,选择自己需要的版本就行wgethttps://repo.anaconda.com/archive/Anaconda3-5.2.0-Linux-x86_

  • phpstrom 2022激活码[最新免费获取]

    (phpstrom 2022激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html…

  • System.setProperty(),System.setProperty

    System.setProperty(),System.setPropertySystem.getProperties()获得所有的系统变量System.getProperty(“os.name”)获取指定的系统变量(获取系统=windows8.1)System.setProperty(“koow”,”123″)储存在系统变量中,变量名为koow,值为123System.getProperty(“koow”)获取指定的系统变量(获取koow=12

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号