详解TCP四次挥手(断开TCP连接过程)
在讲述TCP四次挥手,即断开TCP连接的过程之前,需要先介绍一下TCP协议的包结构。
TCP协议包结构:

这里只对涉及到四次挥手过程的字段做解释
(1) 序号(Sequence number)
我们通过 TCP 协议将数据发送给对方,就比如 hellotcp,这一串字节流,假设被拆分成了三个 TCP 报文段,第一个报文段携带了 hel,第二个报文段携带了 lot,第三个报文段携带了 cp,这三个报文段不一定是按照顺序送到对端的,那么对端收到这三个段是如何确定他们的顺序的呢?此时序号的意义就体现在这里。
TCP 连接中,为传送的字节流(数据)中的每一个字节按顺序编号。也就是说,在一次 TCP 连接建立的开始,到 TCP 连接的断开,你要传输的所有数据的每一个字节都要编号。这个序号称为字节序号。
举个例子:如果一个 TCP 报文段的序号为 101,它携带了 50 字节的数据,就表示这 50个字节的数据的字节序号范围是 [101, 150],该报文段携带的第一个字节序号是 101,最后一个字节序号是 150。
(2) 确认号(Acknowledge number)
TCP传输的对端通过回复一个确认号,来表示确认已经接收到了某个 TCP 段。
举个例子:比如之前发送方发送的序号为 101 的 TCP 段,这个段携带了 50 字节数据,则接收方应当回复的确认号是 151,它表示接收方已经收到了字节序号为150之前的数据,现在期望你发送字节序号为 151 以及以后的数据。
(3)ACK
是一个TCP协议报文中的标志比特位,如果置1表示这个报文段是一个回复确认报文。
注意:为了防止混淆确认号与ACK,一般确认号写作ack,而ACK就写为ACK。
(4)FIN
同样是一个TCP协议报文中的标志比特位,如果置1表示该报文段用来断开TCP连接。
介绍完TCP协议报文的一些基本字段,我们可以来叙述TCP四次挥手的过程了。
TCP四次挥手流程图:

数据传输结束后,通信的双方都可以释放连接。现在A和B都处于ESTABLISHED状态。
(1)第一次挥手
A的应用程序先向其TCP发出连接释放报文段,并停止发送数据,主动关闭TCP连接。A把连接释放报文段首部的FIN置1,其序号seq=x。这时A进入FIN-WAIT-1(终止等待1)状态,等待B的确认(请注意:TCP规定,FIN报文段即使不携带数据,它也要消耗一个序号)。
(2)第二次挥手
B收到连接释放报文段后即发出确认,确认号是ack=x+1,序号为seq=y。然后B就进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层进程,因而从A到B这个方向的连接就释放了,这时的TCP连接处于半关闭状态,即A已经没有数据要发送了,但B若发送数据,A仍要接收。也就是说,从B到A这个方向的连接并未关闭。这个状态可能会持续一些时间。
A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
(3)第三次挥手
若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。这时B发出的连接释放报文段需要置FIN=1。现假定B的序号为z(在半关闭状态B可能又发送了一些数据)。B还必须重复上次已发送过的确认号ack=x+1。这时B就进入了LAST-ACK(最后确认)状态,等待A的确认。
(4)第四次挥手
A在收到B的连接释放报文段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack=z+1,而自己的序号是seq=u+1(根据TCP标准,前面发送过的FIN报文段要消耗一个序号)。然后进入到TIME-WAIT(时间等待)状态(请注意:现在TCP连接还没有释放掉。必须经过时间等待计时器设置的时间2MSL(MSL:最长报文段寿命)后,A才进入到CLOSED状态)。
常见面试问题一:为什么是四次握手,不能是三次握手吗?
答:与之前需要三次握手的原因类似,如果只是三次挥手,那就相当于服务器端发送完第三次挥手的报文后直接进入CLOSED(关闭)状态,假如此时网络出现问题,丢失了第三次挥手的报文,相当于客户端没有收到,那他依旧认为连接没有结束,在一段时间没有收到第二次ACK应答报文后,他会重新发送请求断开连接的报文,但是服务器端已经关闭,不会再接收报文,又形成了类似死锁的情况。
常见面试题二:为什么有CLOSE-WAIT状态?
答:因为服务器端收到断开TCP连接请求时,有可能还有数据没有向客户端发送完毕,需要一段时间来把所有信息传输完毕。
常见面试题三:为什么有TIME-WAIT状态?
答:假设客户端发送完第四次挥手的报文后,直接进入CLOSED(关闭)状态。那么假设此时网络出现问题,报文丢失,那么因为服务器端收不到第四次挥手的ACK报文段,所以认为此时TCP连接还没有断开。然后重发ACK+FIN报文段,但此时客户端已经关闭与其的TCP连接,肯定不会再接收该报文,这样会浪费大量资源。
常见面试题四:什么情况下会出现大量的TIME-WAIT状态?该怎么解决?
答:在高并发且短连接的通信情况下,服务器会出现大量TIME-WAIT状态,这占用了大量的socket,会影响服务器的正常通信服务。
解决方法:
- (1)降低time_wait的时限。
- (2)设置中允许重用time_wait的socket。
- (3)设置快速回收time_wait的socket
详解TCP四次挥手(断开TCP连接过程)的更多相关文章
- TCP四次挥手断开连接详解
TCP四次挥手. 数据传输结束后,通信的双方都可释放连接.现在A和B都处于ESTABLISHED状态.A的应用程序先向TCP发出连接释放报文段,主动关闭TCP连接.A把连接释放报文段的首部FIN置为1 ...
- 计算机网络(五),TCP四次挥手
目录 1.TCP四次挥手详情 2.为什么会有TIME-WAIT状态 3.为什么需要四次握手才能断开连接 4.服务器出现大量CLOSE_WAIT的原因 五.TCP四次挥手 1.TCP四次挥手详情 (1) ...
- TCP ------ TCP四次挥手(断开连接)及断开过程
1.正常情况下,调用close(),产生的其中一个效果就是发送FIN,只有双方都调用close(),才会出现正常的四次挥手. 2.如果是服务器,发起四次挥手是在关闭accept()返回的套接字,而不是 ...
- 计算机网络之tcp四次挥手
TCP的四次挥手(Four-Way Wavehand)1.前言对于"三次握手"我们耳熟能详,因为其相对的简单.但是,我们却不常听见“四次挥手”,就算听过也未必能详细地说明白它的具体 ...
- TCP为什么是三次握手,为什么不是两次或者四次 && TCP四次挥手
这是一个很有意思的问题~ 首先,我们要知道TCP是全双工的,即客户端在给服务器端发送信息的同时,服务器端也可以给客户端发送信息.而半双工的意思是A可以给B发,B也可以给A发,但是A在给B发的时候,B不 ...
- Java网络编程学习A轮_03_抓包分析TCP四次挥手
参考资料: http://www.jellythink.com/archives/705 示例代码: https://github.com/gordonklg/study,socket module ...
- 使用 tcpdump 抓包分析 TCP 三次握手、四次挥手与 TCP 状态转移
目录 文章目录 目录 前文列表 TCP 协议 图示三次握手与四次挥手 抓包结果 抓包分析 TCP 三次握手 数据传输 四次挥手 TCP 端口状态转移 状态转移 前文列表 <常用 tcpdump ...
- 三次握手和四次挥手以及TCP标志位的详细介绍
一.TCP标志位 在讲TCP三次握手和四次挥手之前,先说一下TCP标志位,方便后续的理解. 简单来说,TCP标志位的值代表了当前请求的目的. 标志位一共有6种,分别是: SYN(synchronous ...
- TCP四步挥手的各种状态转换图
对于TCP四步挥手时的各种状态转换,网上有很多资料.但是有很多描述不是很容易理解,甚至是描述错误,不如这篇文章里http://www.cnblogs.com/Jessy/p/3535612.html# ...
随机推荐
- PHP基于Thinkphp5的砍价活动相关设计
近期我们公司项目里陆陆续续有很多为了招引新用户的活动推出,砍价的活动由我来负责,我们的项目是在微信浏览器里供用户浏览访问. 大概描述:进入砍价活动列表页选择有意向的商品,用户点击商品图片可以看到WEB ...
- javaweb图书管理系统之账号密码验证登录
验证账号与密码是否正确功能 一.注册功能 首先,在验证账号与密码是否正确的前提下的,需要先注册一个账号,如果没有账号,就会进不去,也无法验证. 其实,注册功能就是一个添加的功能,仿照我的第一篇文章,往 ...
- 学习如何运用GitHub网站+出现的问题+Git基本操作总结
首先介绍一下GitHub网站: github是一个基于git的代码托管平台. GitHub 拥有一个非常鼓励合作的社区氛围.这一方面源于 GitHub 的付费模式:私有项目需要付费,而公共项目完全免费 ...
- SpringBoot 项目搭建(详细介绍+案例源码)
SpringBoot 项目搭建 SpringBoot 项目整合源码 SpringBoot 项目整合 一.项目准备 1.1 快速创建 SpringBoot 项目 1.2 标准项目结构图如下 1.3 添加 ...
- js判断输入数字是否是整数,金额、数字
function isIntNum(strNum){//js判断输入数字是否是整数 仅供学习思想 var strCheckNum = strNum+""; if(strCheckN ...
- for循环打印九九乘法表
学习目标: 熟练掌握 for 循环的使用 例题: 需求:打印九九乘法表 代码如下: // 九九乘法表 // row 为行,col为列 for(int row = 1; row < 10; row ...
- maven项目中各文件都没有报错,但是项目名称有红叉
项目报错可以看到Problems(可以在Window--Show View--other--输入Problems找到) 一.可能原因 1.项目中各文件没有报错,但是项目名称中 ...
- 彻底弄懂小程序e.target与e.currentTarget
一.小程序中关于事件对象 e 的属性中有两个特别重要的属性:target与currentTarget属性:对于这两个属性,官方文档上的解释是: target:事件源组件对象 currentTarg ...
- 使用flex的同时设置超出喜爱是省略号,
超出宽度,显示省略号 overflow:hidden; white-space:nowrap; text-overflow:ellipsis; 需要注意的是,在移动端在flex元素中的内容进行省略文字 ...
- VUE3 之 使用 Mixin 实现代码的复用 - 这个系列的教程通俗易懂,适合新手
1. 概述 老话说的好:舍得舍得,先舍才能后得. 言归正传,今天我们来聊聊 VUE 中使用 Mixin 实现代码的复用. 2. Mixin 的使用 2.1 不使用 Mixin 的写法 <body ...