详解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# ...
随机推荐
- web开发者踏入人工智能的利器_Tensorflow.js
前言 最近公司向员工搜集公司杂志的文章,刚好最近学习了机器学习相关课程.为了赚取购买课程的费用,所以写了如下文章投稿赚取稿费. 如下文章可能涉及一些我所购买课程的内容,所以不便将所有资源进行展示. 当 ...
- iframe引入微信公众号文章
微信在文章页面设置了响应头""frame-ancestors 'self'"阻止了外部页面将其嵌套的行为,文章的图片也设置了防盗链的功能,这就导致了直接在iframe中引 ...
- webpack 4.0 配置方法以及错误解决
选取一个空目录来试验 全局安装webpack4.1之后 创建目录 mkdir webpacktest && cd webpacktes 初始化package.json npm init ...
- crm单元测试使用
Action使用 使用paramBag传递入参,填写入参名,入参值,后使用 serviceProvider传入插件. Assert.AreEqual(this.output["state&q ...
- linux下elf二进制文件怎么回事(ls,vmstat等命令)
这个实验有两个目的: 1.linux的可执行命令例如:ls .cd等都是二进制elf格式文件等,后面的逻辑是什么,我们怎么窥探底层内容. 2.ELF可执行文件默认从地址0x080480000开始分配 ...
- msyql查看版本号、最大连接数、当前连接数等
1.查看版本号 select version(); 2.查看最大连接数 show variables like 'max_connections'; 3.查看当前连接数(如果是root帐号,你能看到所 ...
- 3.Docker容器学习之新手基础使用
原文地址: http://blog.weiyigeek.top/2019/5/2-docker%E5%AD%A6%E4%B9%A0%E4%B9%8B%E5%9F%BA%E7%A1%80%E4%BD%B ...
- 解决zabbix5字体中文口口乱码
环境信息 系统:Ubuntu20.04 zabbix版本:5.4 解决方法一 此方法比较偷懒,就是不改变zabbix相关配置,直接用原名替换字体文件. 原字体字体名称为DejaVuSans.将方法二的 ...
- NodeJS学习日报day4——模块化
// console.log(module); // 执行顺序不同,结果也不同 // module.exports = { // name : 'Cra2iTeT', // hi() { // con ...
- Nuxt 的介绍与安装
Nuxt.js(一.介绍与安装) 1.为什么使用Nuxt 渐进式Vue.js框架给前后端分离带来无限的乐趣,越来越多的程序员选择Vue.在我们使用Vue框架的过程中不免会出现以下的一些问题: 如何更好 ...