四次挥手 TIME_WAIT 存在的理由

在这里插入图片描述

1 可靠地实现TCP全双工连接的终止

在四次挥手第 4 阶段,client发送的确认报文可能会丢失。
如果该ACK报文丢失,过一段时间server会重新发送FIN报文给client( 步骤3 )。
如果没有TIME_WAIT等待的时间(即,client收到步骤3发的FIN后,发送完ACK后就立即关闭)。
那么此时的client 已经关闭,client在收到未连接的报文后,会发送给对方一个RST报文,告诉对方出现的错误连接。
而通过RST报文来关闭TCP连接,破坏了TCP连接正常释放的流程。

2 允许老的重复分节在网络中消逝

在TCP连接关闭前,可能有部分数据包“迷路”了,在TCP连接准备关闭时,有数据还在“赶来的路上”,而我们如果直接关闭连接就会造成,“迟来的”数据包到达目的主机时连接已关闭的情况。
主机在收到未连接的TCP发送的报文时,会发送一个RST报文回去告知对方连接错误,而这种TCP关闭的方式也是破坏了TCP连接正常释放的流程。

综上,TIME_WAIT的等待时间是必要的。

有关RST报文参考:
TCP异常终止(reset报文)
RST报文详解

附 tcp状态转移图
在这里插入图片描述


以下引用自《windows 网络编程》一书:

5.1.3 TCP连接的建立与终止

为了建立一条TCP连接,需要以下三个基本步骤:
1)请求端(通常称为客户)发送一个SYN报文段指明客户打算连接的服务器端口号,以及初始序号(Initial Sequence Number,ISN),SYN请求发送后,客户进入SYN_SENT状态。

2)服务器启动后首先进入LISTEN状态,当它收到客户发来的SYN请求后,进入SYN_RCV状态,发回包含服务器的初始序号的SYN报文段作为应答,同时将确认序号设置为客户的初始序号加1,对客户的SYN报文段进行确认。一个SYN将占用一个序号。

3)客户接收到服务器的确认报文后进入ESTABLISHED状态,表明本方连接已成功建立,客户将确认序号设置为服务器的ISN加1,对服务器的SYN报文段进行确认,当服务器接收到该确认报文后,也进入ESTABLISHED状态。

这三个报文段完成连接的建立,这个过程称为“三次握手”,如图所示。
在这里插入图片描述
一般由客户决定何时终止连接,因为客户进程通常由用户交互控制,比如Telnet的用户会键入quit命令来终止进程。既然一个TCP连接是全双工的(即数据在两个方向上能同时传递),那么每个方向必须单独关闭。终止一个连接要经过四次交互,当一方完成它的数据发送任务后,发送一个FIN报文段来终止这个方向的连接。当一端收到FIN,它必须通知应用层另一端已经终止了那个方向的数据传送。发送FIN通常是应用层进行关闭的结果。下图显示了终止一个连接的典型握手顺序。首先进行关闭的一方(即发送第一个FIN)将执行主动关闭,而另一方(收到这个FIN)执行被动关闭,具体步骤如下:

1)客户的应用进程主动发起关闭连接请求,它将导致TCP客户发送一个FIN报文段,用来关闭从客户到服务器的数据传送,此时客户进入FIN_WAIT_1状态。

在这里插入图片描述
2)当服务器收到这个FIN,它发回一个ACK,进入CLOSE_WAIT状态,确认序号为收到的序号加1。与SYN一样,一个FIN将占用一个序号。客户收到该确认后进入FIN_WAIT_2状态,表明本方连接已关闭,但仍可以接收服务器发来的数据。

3)接着服务器程序关闭本方连接,其TCP端发送一个FIN报文段,进入LAST_AC状态,当客户接收到该报文段后进入TIME_WAIT状态

4)客户在收到服务器发来的FIN请求后,发回一个确认,并将确认序号设置为收到的序号加1。发送FIN将导致应用程序关闭它们的连接,服务器接收到该确认后,连接关闭。这些FIN的ACK是由TCP软件自动产生的。

在实际应用中,服务器也可以作为主动发起关闭连接的一方,如果交换图中的服务器和客户位置,其通信过程不变。

我们注意到在如图所示的连接关闭过程中,当四次交互完成后,客户并没有直接关闭连接,而是进入TIME_WAIT状态,且此状态会保留两个最大段生存时间(2MSL),等待2MSL时间之后,客户也关闭连接并释放它的资源。

为什么需要TIME_WAIT状态呢?设立TIME_WAIT有两个目的:

1)当由主动关闭方发送的最后的ACK丢失并导致另一方重新发送FIN时,TIME_WAIT维护连接状态。当最后的ACK发生丢失时,由于执行被动关闭的一方没有接收到最后序号的ACK,则会运行超时并重新传输FIN。假如执行主动关闭的一方不进入TIME_WAIT状态就关闭了连接,那么此时重传的FIN到达时,由于TCP已经不再有连接的信息了,所以它就用RST(重置连接)报文段应答,导致对等方进入错误状态而不是有序终止状态。由此看来,TIME_WAIT状态延长了TCP对当前连接的维护信息,对于正确处理连接的正常关闭过程中确认报文丢失是很有必要的。

2)TIME_WAIT为连接中“离群的段”提供从网络中消失的时间。IP数据包在广域网传输中不仅可能会丢失,还可能延迟。如果延迟或重传报文段在连接关闭之后到达,通常情况下,因为TCP仅仅丢弃该数据并响应RST,当该报文段到达发出延时报文段的主机时,因为该主机也没有记录该连接的任何信息,所以它也丢弃该报文段。然而如果两个相同主机之间又建立了一个具有相同端口号的新连接,那么离群的段就可能被看成是属于新连接的,如果离群的段中数据的任何序号恰好处在新连接的当前接收窗口中,数据就会被新连接接收,其结果是破坏新连接,使TCP不能保证以顺序的方式递交数据。因此TIME_WAIT状态确保了旧连接的报文段在网络上消失之前不会被重用,从而防止其在上述情况下扰乱新连接。

通常情况下,仅有主动关闭连接的一方会进入TIME_WAIT状态。RFC793中定义MSL为2分钟,在这个定义下,连接在TIME_WAIT状态下保持4分钟,而实际中,MSL的值在不同的TCP协议实现中的定义并不相同。如果连接处于TIME_WAIT状态期间有报文段到达,则重新启动一个2MSL计时器。

在客户和服务器建立连接和断开连接的交互过程中,双方端点所经历的TCP状态发生了多次转换,当发生网络环境异常时,这些状态的变迁有助于理解和解释基于流式套接字的应用程序在运行中的表现。

热门文章

编程学习 ·

Android运行Linux程序

安卓直接运行arm-linux-gnueabi-gcc编译的标准嵌入式Linux程序,我们有时不想把原Linux程序重新开发一遍。第一步,给adb root权限运行,否则拷贝会提示无权限failed to copy E:\share\a8Agent1.0.1\a8Agent to /data/a8Agent: Permission deniedadb root 第二不,发送程序到安…
编程学习 ·

C语言期末考试内容(2)选择填空答案整理(基础章节内容)

C语言期末考试内容(2)选择填空答案整理(基础章节内容)文章目录C语言期末考试内容(2)选择填空答案整理(基础章节内容)作业二:变量定义/读/写与数据的存储表示一、判断题:答案: F F F F解析:1-4:C语言中的结束符是以分号来结束的,一个分号就代表一条语句。二、单选…
编程学习 ·

PAT 1161 Merging Linked Lists

原题链接:暂无 关键词:链表 Given two singly linked lists L 1 =a 1 →a 2 →…→a n−1 →a n L1=a1→a2→…→an−1→an and L 2 =b 1 →b 2 →…→b m−1 →b m L2=b1→b2→…→bm−1→bm . If n≥2m n≥2m , you are supposed to reverse and merge the shorter one i…
编程学习 ·

C语言实现为终端程序--webshell基石

之前对ssh一直很困惑它是如何实现的,网上也没有相关代码实例,所以自己花了一段时间研究了一下。本篇博客主要写了两个程度:服务端和客户端,通过客户端可以远程登录服务端,执行shell命令。代码实现的比较糙,但是基本原理一看就明白。一、主要核心思想:1)创建pty虚拟终端…
编程学习 ·

MySQL 简洁速查手册

MySQL 速查手册 文章目录MySQL 速查手册0. 前言1. 开启/关闭数据库2. 数据库操作3. 数据表操作4. 字段操作5. 数据操作6. 运算符7. 高级查询(group by、having、order by、limit)8. 高级插入9. 高级删除10. 高级更新11. 联合查询12. 连接查询12.1 左外连接12.2 右外连接13. 子查…
编程学习 ·

工科中的设计思维

超星学习通app工科中的设计思维网课答案,工科中的设计思维尔章节测验网课答案1.1 走近设计思维1【单选题】本门课程讲述的主要内容不包括()。A、设计思维这一学习形式和思维方式B、一系列有用的创新工具和创造技法C、工科学生需要用到的专业设计软件D、系统化的设计流程和与众…
编程学习 ·

3D打印与互联网发展的探索

“互联网+3D打印+创意文化”模式崭露头角 互联网具备大众属性,3D打印技术及服务或许能结合互联网带来更多创新,通过互联网渠道带来全流程的在线、交互体验、互联网化来实时响应消费用户需求形成新的商业模式。 近日,国内一家3D打印综合性服务平台已悄然上线,为消费用户提供…
编程学习 ·

machine learning基础知识(Leetcode)

机器学习 machine learning是机器通过已知的内容,类似于人类一样进行学习,并对同类型数据进行判断的过程。 例如训练图片模型就是将每个像素点转为0到255之间的值,利用机器发现不同种类的图片之间存在的映射。 有监督与无监督模型监督学习是F(x)= sum 并且sum已知,可以通…
编程学习 ·

02 | 该如何选择消息队列?

1.应用场景见: https://blog.csdn.net/william_n/article/details/1040254082.学习/操作2.1 阅读文档02 | 该如何选择消息队列?李玥 2020-01-1400:0013:59讲述:李玥 大小:12.81M你好,我是李玥。这节课我们来聊一下几个比较常见的开源的消息队列中间件。如果你正在做消息队…
编程学习 ·

IDEA常用快捷键或修改为Eclipse快捷键风格

Ctrl + Y 删除当前行 Ctrl + D 复制当前行到下一行 Ctrl + Z 撤销 Alt+Enter 导入包,自动修正 Ctrl+F 查找文本 Ctrl+U 大小写切换 Ctrl+W 选中代码,连续按会扩大范围 Ctrl+R 替换文本快捷键改为eclipse快捷键风格Ctrl+Alt+S 或者打开File选择Settings这就完成了
编程学习 ·

git命令大全

Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git官方网站:https://git-scm.com/ 原理图Workspace:工作区 Index / Stage:暂存区 Repository:仓库…
编程学习 ·

进程保活

进程保活一.为什么需要进程保活二.进程优先级前台进程(Foreground process)可见进程(Visible process)服务进程(Service process)后台进程(Background process)空进程(Empty process)三.保活方式1. 利用 Notification 提升权限2. 利用系统Service机制拉活3. 添加Manifest文件属…
编程学习 ·

windows10系统-2-安装Nodejs及SocketIO

(1)双击node-v12.14.1-x64.msi CMD>npm --version查看npm的版本 CMD>npm -v (2)使用淘宝镜像的命令 CMD>npm install -g cnpm --registry=https://registry.npm.taobao.org CMD>npm list -g查看所有全局安装的模块 【全局安装所在路径C:\Users\user\AppData\Roamin…
编程学习 ·

五篇机器阅读理解论文(Match-LSTM+Ptr,DCN,R-Net,QANet)介绍

以close-domain为例,MRC任务就是给定一篇文章和一些与文章相关的问题,要求模型给出问题的答案 MRC按照问答的形式不同大致可以分成四种任务填空型 多项选择型 片段抽取型 自由答案型首先来看一看数据集 填空型问答 所谓填空型问答是指给定一篇文章和一个缺失某个单词的句子作…
编程学习 ·

字节,位,字长

文章目录位,字节,字长换算位字长字符,字符集,字符编码常见字符集的编码:ASCII 字符集:GB2312 字符集:GBK 字符集:BIG5 字符集:GB18030 字符集:ISO8859-1:Unicode 字符集:UTF-16 与 UTF-8:总结 位,字节,字长 位:bit 最小单元 又叫比特数.在数字世界里没有电影、…
编程学习 ·

项目实训——初版的页面优化(2)

项目实训——初版的页面优化(2)题目太长的解决就业帮助具体内容的收起展开表格的美化 再次进行了一次小组会议,找到了更加多的需要优化和完善的地方。比如题目很容易出框,讨论区话题的显示需要限制长度等等。同时也新增一些功能,比如评论的删除。这篇先写完善。 题目太长的…
编程学习 ·

多线程编程六-线程池的使用

目录1 JDK自带的线程池2 七大参数简介:3 线程池工作流程4 自定义拒绝策略5 和spring整合6 合理配置线程数1 JDK自带的线程池我们知道JDK可以通过Executors类来创建线程池,但是这些线程池都有缺点,所以在生产环境中我们要自定义线程池来使用 Executors.newFixedThreadPool(),…