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

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

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. 【漫画】CAS原理分析!无锁原子类也能解决并发问题!

    本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...

  2. 如何搭建一个WEB服务器项目(三)—— 实现安卓端联网登录

    安卓端调用服务器登录函数进行验证登录 观前提示:本系列文章有关服务器以及后端程序这些概念,我写的全是自己的理解,并不一定正确,希望不要误人子弟.欢迎各位大佬来评论区提出问题或者是指出错误,分享宝贵经验 ...

  3. 「雕爷学编程」Arduino动手做(13)——触摸开关模块

    37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...

  4. POJ3903 Stock Exchange LIS最长上升子序列

    POJ3903 Stock Exchange #include <iostream> #include <cstdio> #include <vector> #in ...

  5. Centos7访问Win7/Win10系统中的共享文件

    服务器挂在U盘: 1.先将U盘格式化为Fat格式或其他服务器能识别的格式. 2.使用fdisk -l,找到自己的U盘(根据盘大小) 3.新建一个文件夹(mkdir /mnt/usb)用于挂在数据 4. ...

  6. MVC4.0接口学习

    /// <summary> /// 正则验证身份证号是否合法 /// </summary> /// <param name="sIdCard"> ...

  7. Linux文件列表查询ll和ls区别

    ll ll查询文件列表,查询结果为当前目录下文件和文件夹的详细信息,包括权限.根目录.用户.创建时间等. ls ls查询出的查询结果只显示当前目录下文件夹和文件名称

  8. Web前端:2、盒模型的组成

    在HTML中,若想要实心划分区域,则:1.添加标签:2.对标签设置尺寸(宽高) 但只要是添加了一个元素(标签),就会在页面中生成一个盒子,不同元素产生的盒子模型可能不同,这取决于它CSS的displa ...

  9. multipart_formdata

    import requests def sendImg(img_path, img_name, img_type='image/jpeg'): """ :param im ...

  10. linux高级管理第十二章--rsync

    实验部分 1.安装rsync 2.配置文件 3.配置密码 4.后续 5.为了测试,创建几个文件 配置实时同步 1.调整inotify内核参数 安装inotify-tools 测试同步 编写脚本 验证 ...