前面进行“三次握手”建立连接后,当客户端的数据发送完毕,它就会要求与服务器端断开连接,那么就要进行“四次挥手”进行连接的释放。

  注意,此处所谓的“客户端”与“服务器端”,只是为了方便标识连接的双方,即确认哪一方是“要求断开连接”的主动方,哪一方是“要求断开连接”的被动方。事实上任何一方都可能在发送完数据后要求与另一方断开连接。

1、“四次挥手”过程

  如下图:

  “四次挥手”的具体过程如下:

1)“第一次挥手”:首先,客户端已经发送完数据,想要释放连接(客户端是释放连接的主动方),向服务器端发送一段TCP报文,其中:

  i)标记位 FIN=1:表示这个TCP请求是“请求释放连接”;

  ii)报文的序号 seq=u:u 等于前面客户端已经传送的数据的最后一个字节的序号加1;

  iii)客户端由“ESTABLISHED”连接建立状态,进入“FIN-WAIT-1”终止等待状态1。此时客户端不会再向服务器端发送数据。

需要注意,FIN报文虽然不携带数据,但是但是它会消耗一个字节序号。即客户端第一次发送的FIN报文 seq=u,报文会消耗一个序号,那么客户端下次发送的报文应该从 seq=u+1 开始发送。

2)“第二次挥手”:服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,会发送回一个TCP报文,其中:

  i)标记位为ACK=1:表示“服务器端告知客户端,自己已经接收到客户端发送的释放连接的请求”;

  ii)报文序号 seq=v:服务器端到客户端的连接还没有关闭,服务器端还会向客户端发送数据包,这个报文序号为 v;

  iii)确认号ack = u+1:表示希望客户端下一个报文的序号是 u+1,即希望客户端下一个报文从序号为 u+1 的字节开始发送。我们知道客户端第一个报文 seq=u,且该报文为FIN报文,占一个序号,那么客户端下一个报文就应该从 u+1 开始发送。

  iv)服务器端结束 “ESTABLISHED” 连接阶段,进入“CLOSE-WAIT” 关闭等待状态;

此时从 客户端到服务器端 这个方向的连接就被释放,TCP连接处于“半关闭状态” 。 此时客户端不会再向服务器端发送数据,但是服务器端可能还会想客户端发送数据。

  v)客户端收到从服务器端发出的TCP报文之后,确认了服务器端收到了客户端发出的释放连接请求,随后客户端结束“FIN-WAIT-1”终止等待状态1,进入“FIN-WAIT-2”终止等待状态2。

总结:前两次挥手,既让服务器端知道了客户端想要释放连接,也让客户端知道了服务器端知道了自己想要释放连接。

3)“第三次挥手”:客户端经过 “ClOSE-WAIT” 关闭等待 状态后,它要发送给服务器端的数据也发送完毕,即它做好了释放服务器端到客户端连接的准备,就会想客户端发送一段FIN的TCP报文:

  i)标记位 FIN=1,ACK=1:表示“服务器端告知客户端,自己已经做好释放连接的准备”;

  ii)报文序号 seq=w:关闭等待阶段,服务器端可能又向客户端发送了数据,因此此时 seq 不是v,而是最新的数据 w;

  iii)确认号 ack=u+1:还是希望客户端下一次发送的报文序号为 u+1;

  iv)发送“第三次挥手”报文后,服务器端进入“LAST-ACK” 最后确认阶段。此后,服务器端再也无法向客户端发送数据。

注意,第三次挥手发送的是FIN的报文,没有数据但是会占一个序号,即下一次服务器端发送的报文序号 seq=w+1。

4)“第四次挥手”:客户端接收到服务器端“第三次挥手”的报文后,确认服务器端已经做好断开连接的准备,会向客户端发送“第四次握手”的报文:

  i)标记位ACK=1:表示“客户端已经知道服务器端做好释放连接的准备”;

  ii)ack = w+1:将收到服务器端报文的 seq+1,作为自己的ack。表示希望服务器端下次发送的报文的序号为 w+1;

  iii)seq=u+1:将收到服务器端报文的 ack 作为自己的 seq,因为服务器端报文 ack=u+1 表示希望客户端这次发送的报文序号是 u+1,那么客户端这次发送报文的序号就设置为 u+1;

  iv)客户端发送完第四次挥手的报文后,启动等待计时器,等待2MSL后,如果没有收到服务器端新的请求,就进入“CLOSED” 连接关闭状态;

  v)服务器端在收到客户端发送的第四次挥手的报文后,进入进入“CLOSED” 连接关闭状态。

总结:后“两次挥手”既让客户端知道了服务器端准备好释放连接了,也让服务器端知道了客户端了解了自己准备好释放连接了。于是,可以确认关闭服务器端端到客户端方向上的连接了,由此完成“四次挥手”,关闭了连接。

2、三个关键问题

1)为什么“握手”是三次,而“挥手”却是四次?

  对于“三次握手”,在第二次握手的时候,服务器端向客户端发送的报文的标记位包含 SYN=1以及ACK=1,SYN是请求连接标志,表示服务器端同意建立连接;ACK是确认报文,表示告诉客户端,服务器端收到了它的请求报文。即“确认接收”与“同意连接”是在同一次握手中传输的。那么通过三次握手就刚刚好可以建立连接;

  对于“四次挥手”,第二次挥手的时候,服务器端可能还没有做好关闭连接的准备(它可能还有数据要发送给客户端),因此,它不会立即释放连接,会在第二次挥手先返回一个ACK=1,表示已经接受到客户端的断开连接的请求。随后,客户端处理完数据后,会发送第三次挥手报文,其中FIN=1,表示服务器端已经准备好释放连接。因此,释放连接需要经过“四次挥手”。

2)为什么客户端要在发送第四次挥手的报文后等待2MSL的时间才进入CLOSED状态?

  目的是为了确认服务器端会收到客户端发送的“第四次挥手”的ACK确认报文。

  MSL(Max Segment Lifetime): 最长报文段寿命,也就是一个报文在网络中存活的最长时间,一般设置为2分钟。当客户端发出最后的ACK确认报文时,并不能确定服务器端能够收到该段报文。所以客户端在发送完ACK确认报文之后,会设置一个时长为2MSL的计时器。

  在1MSL的时候,如果服务器端没有收到客户端发送的ACK确认报文,就会再次向客户端发送FIN报文,这个报文在1MSL的时间内会到达客户端,此时客户端边知道自己上一次发送的ACK确认报文没有发送到服务器端,于是客户端会再次向服务器端发送ACK确认报文,并将等待计时器重置。

  如果在2MSL的时间内没有接受到服务器端发送回来的FIN报文,说明客户端最后发送的ACK确认报文已经被服务器端接收到,可以关闭连接。因此,事实上客户端会比服务器端更晚进入CLOSED状态。

3)如果已经建立了连接,但是客户端出现故障了怎么办?

  如果客户端发送错误,服务器端还一直保持连接,这个连接并不会传送数据,并且占用了服务器端的资源。服务器端有一个“保活计时器”,服务器端每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若2小时还没有收到客户端的任何数据,客户端就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文客户端仍然没反应,服务器端就认为客户端出了故障,接着就关闭连接。

TCP协议“三次握手”与“四次挥手”详解(下)的更多相关文章

  1. TCP协议三次握手与四次挥手详解

    在计算机网络的学习中TCPi协议与Http协议是我们必须掌握的内容,其中Tcp协议属于传输层,而Http协议属于应用层,本博客主要讲解Tcp协议中的三次握手与四次挥手,关于Http协议感兴趣的可以参看 ...

  2. TCP协议“三次握手”与“四次挥手”详解(上)

    在使用TCP协议进行数据的传输之前,客户端与服务器端需要建立TCP Connection,即建立连接,之后两端才能进行数据的传输. 下面堆TCP连接“三次握手”的过程进行说明. 1.相关概念 首先,我 ...

  3. TCP的三次握手与四次挥手详解

    TCP的三次握手与四次挥手是TCP创建连接和关闭连接的核心流程,我们就从一个TCP结构图开始探究中的奥秘  序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序 ...

  4. TCP的三次握手和四次挥手详解

    相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不需要控制这个过程.但是对于理解TCP底层运作机制,相当有帮助. TCP报文格式 TCP的包如下: ...

  5. TCP三次握手与四次挥手详解

    目录 TCP三次握手与四次挥手详解 1.TCP报文格式 2.TCP三次握手 3.TCP四次挥手 4.为什么建立连接需要三次握手? 5.为什么断开连接需要四次挥手? 6.为什么TIME_WAIT状态还需 ...

  6. TCP/IP的三次握手与四次挥手详解

    TCP((Transmission Control Protocol)传输控制协议,是一个面向连接的协议.在运用此协议进行数据传输前都会进行连接的建立工作(三次握手):当数据传输完毕,连接的双方都会通 ...

  7. TCP三次握手与四次挥手详解(最全面)

    目录 TCP的三次握手与四次挥手 TCP报文段的首部格式 TCP的工作原理 TCP 的流量控制 TCP的拥塞控制 拥塞控制与流量控制的关系 拥塞控制所起的作用 慢开始和拥塞避免 慢开始算法的原理 三次 ...

  8. TCP协议三次握手与四次挥手通俗解析

    TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式 TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷本.下面是TCP报文格式图: 图1 TCP报文格式 上图中有几个字 ...

  9. [ 转载 ] Tcp三次握手和四次挥手详解

    #TCP的报头: 源端口号:表示发送端端口号,字段长为16位.目标端口号:表示接收端口号,字段长为16位.序列号:表示发送数据的位置,字段长为32位.每发送一次数据,就累加一次该数据字节数的大小.注意 ...

随机推荐

  1. eclipse导入工程报错-项目或者文件有红叉的解决方案

    1.Java的JDK或者Tomcat版本不一致 像这样的我们首先找到项目---->Build Path--->Config BuildPath,将找不到的JDK或者Tomcat进行删除和添 ...

  2. 干货分享:如何使用Kubernetes的Ingress API

    您可以通过使用诸如Kong for Kubernetes的Ingress控制器(使用自定义资源定义并提供许多插件)来极大地扩展Ingress资源的功能. Kubernetes正在整个技术行业中得到采用 ...

  3. 从零开始实现ASP.NET Core MVC的插件式开发(七) - 近期问题汇总及部分解决方案

    标题:从零开始实现ASP.NET Core MVC的插件式开发(七) - 问题汇总及部分解决方案 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/12 ...

  4. CDH6 高版本hbase+solr实现二级索引

    之前的环境是单独下载的CDH组件包搭建的集群,但是因为hadoop版本过低导致漏洞无法修复,重新搭建高版本集群环境. 新集群环境: 主要组件:hadoop,hbase,zookeeper,Key-Va ...

  5. oracle [精华] 你是否仍迷信rowid分页?

    http://www.itpub.net/thread-1603830-1-1.html

  6. mysql单记录也能造成的死锁

    最近在开发的时候,在mysql Innodb 引擎下,一条记录记录也能引起锁的事件. 场景描述 在项目压测的是,突然发现有类似以下的异常发生: com.mysql.jdbc.exceptions.jd ...

  7. 模板:DOM常用场景【表单提交】——javascript结合HTML DOM(或者JQuery)运用

    一.删除行为前的提示 首先要有一个onclick的DOM(点击)事件,和一个JavaScript弹出框:confirm()确认框 <script> function del(){ var ...

  8. 干货 | Kafka 内核知识梳理,附思维导图

    前面我们已经分享过几篇Kafka的文章,最近简单梳理了下Kafka内核相关的知识,涵盖了Kafka架构总结,副本机制,控制器,高水位机制,日志或消息存储,消息发送与消费机制等方面知识.文末含对应的Ka ...

  9. Win10上禁用Device Guard以便运行VMware

    Win10上每次大版本升级后,如果你试图运行VMware,都会提示如下的错误信息: “VMware Workstation 与 Device/Credential Guard 不兼容.在禁用 Devi ...

  10. TP5.0登录验证码实现

    <div class="loginbox-textbox"> <input class="form-control" placeholder= ...