TCP/IP 四次断开
网络连接状态
网络连接状态(11种)非常重要这里既包含三次握手中的也包括四次断开中的,所以要熟悉。
- LISTEN 被动打开,首先服务器需要打开一个socket进行监听,监听来自远方TCP端口的连接请求,等于服务器端执行socket、bind、listen三个函数之后阻塞在accept处。
- SYN_SENT 表示主动连接,客户端能通过应用程序调用connect()函数进行active open。于是客户端TCP发送一个SYN以请求建立一个连接,之后状态为SYN_SEND,表示已发送一个SYN到服务器端,等待SYN 1+ACK 0响应。
- SYN_RECV 服务器端收到客户端的SYN 1,然后状态变为SYN_RECV。表示服务器收到了客户端发来的SYN,然后自己也响应了给客户端一个SYN 1+ACK 1,然后等待客户端确认。 这时候客户端过来的连接(属于半连接状态)被放在一个SYN队列里面,SYN泛洪***也是这样的,就是服务器响应了SYN+ACK之后,客户端就不在发送ACK了,然后继续发送SYN,直到把服务器的最大连接数量耗尽。 半连接队列长度是由内核参数tcp_max_syn_backlog来决定的。
- ESTABLISHED 代表一个打开的连接,客户端收到服务器发送的SYN 1+ACK 1,就变为这个状态,然后向服务器发送ACK,如果服务器收到这个ACK,那么它也变为这个状态。这个状态就是表示连接以及建立,正在或即将传输数据。服务器收到ACK以后就会把半连接从上面提到的SYN队列中删除,然后放到ACCEPT队列中,这时这个半连接的状态就变成了ESTABLISHED。
- FIN_WAIT1 主动关闭端(可以是服务器也可以是客户端)应用程序调用了close,于是其TCP发出FIN主动关闭请求,也就是四次断开的第一次,之后就进入了FIN_WAIT1状态,等待远程主机的ACK请求。
- CLOSE_WAIT 被动关闭端(可以是服务器有可以是客户端)收到了对方发来的FIN后,进入该状态,然后发出ACK+1以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序)。这个状态实际上是说客户端告诉服务器我没有请求或者数据要发送了,等待看看服务器或者说是进程还有没有数据要发送,如果有则继续发送,如果没有的话,就发送反向关闭指令。如果服务器大量连接是这个状态就要去查看程序,很有可能是程序设计的问题。
- FIN_WAIT2 主动关闭端收到ACK+1后,就进入的FIN_WAIT2状态,也就等服务器是否还有数据发来,如果服务器没有数据了,那么服务器就发送的反向关闭指令。也就是反向关闭连接指令FIN1+ACK1。实际上是告诉客户端我的数据发送完了,可以关闭连接了。
- LAST_ACK 被动关闭端,发送反向结束连接请求FIN 1+ACK 1,然后进入LAST_ACK状态,等待主动关闭端发送ACK。
- TIME_WAIT 主动关闭端收到FIN 1 +ACK 1后,并进入TIME_WAIT状态,然后发送ACK+1,等待一段时间(2MSL)以确保服务器收到了ACK+1,然后自己进入CLOSED状态。这个阶段主要是客户端为了再次确认一下服务器是否可以关闭连接,因为网络毕竟是不可靠的。对于服务器有大量TIME_WAIT这个问题通常调整sysctl来解决。
- CLOSING 比较少见,表示等待远程TCP对连接中断的确认。
- CLOSED 被动关闭端在收到ACK包以后,就进入closed状态,连接结束。
四次断开过程
客户端:发送FIN给服务器表示主动请求断开连接,然后自己进入FIN_WAIT1阶段,等待服务器响应
服务器:收到客户端的FIN请求,发送ACK给客户端表示自己同意断开连接,服务器告诉上层【应用程序】有一个连接要请求断开并且进入CLOSE_WAIT阶段,等待应用程序做好关闭准备,其实就是把还没有传送完的数据传送完毕。
客户端:收到ACK以后进入FIN_WAIT2状态等待服务器发送FIN。
服务器:当应用程序做好关闭连接的准备后则发送FIN给客户端,并且服务器进入LAST_ACK阶段,等待客户端最后确认。
客户端:收到服务器的FIN以后发送ACK表示确认,此时客户端进入TIME_WAIT阶段,它并不是等什么确认而是等一段时间保证ACK可以有足够的时间被服务器收到,这个时间为1-4分钟。之后连接关闭。
服务器:收到客户端的ACK以后关闭连接。
关于MSL时长
任何TCP实现必须选择一个MSL值,有两种规范一种是一个MSL是2分钟,另外一种是30秒,所以这就意味着TIME_WAIT状态的持续时间为1-4分钟。MSL也是IP数据包在互联网上能存活的最长时间。另外我们追踪一个IP包的时候会有跳数概念,最大跳数255,所以即便到达最大跳数也不能超过一个MSL时间。
那为什么等2个MSL而不是1个或者3个呢?
IP数据包的最大存活时长是1个MSL,如果1个MSL内客户端发送的ACK丢了那么服务器肯定会重发最后一个FIN,而最后一个FIN这个数据包的最大存活时间也是1个MSL,所以客户端如果在2MSL时间内又收到服务器发来的FIN,就表示之前客户端发送的ACK确实丢了,这时候客户端会再次发送ACK。所以设置为1个太短,3个没必要。
关于TIME_WAIT的作用
- 客户端发送最后的ACK以后,如果服务器端收不到那么服务器会重发FIN,所以在1一个MSL时间内是为了确保客户端可以收到服务器重发的FIN(如果有必要)
- 如果在1MSL内服务器没有重发FIN,表示服务器已经收到客户端最后的ACK,那么也就表示双方都正常关闭了连接
- 在TIME_WATI阶段,主动关闭的一方不能重新建立一个和之前一样的连接,这是为了避免造成属于上一个连接的数据被归属到这次新连接,所以经过2MSL之后属于之前连接的数据包能到的也就到了不能到的也就被丢弃了,同时对于服务器来说它的应答数据也最多存活1MSL。
为什么上图的主动关闭是客户端
其实任何一方都可以主动关闭,只是我们在实际过程中双方通信肯定有一方作为客户端角色一方作为服务器角色存在,所以这里只是一个角色并不是说服务器不能主动关闭。在这里你需要牢记的是主动关闭和被动关闭的一方各自都会有什么状态。
TCP/IP 四次断开的更多相关文章
- tcp/ip四次挥手
四次分手: 由于TCP连接是全双工的,因此每个方向都必须单独进行关闭.这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接.收到一个 FIN只意味着这一方向上没有数据流动,一个 ...
- TCP/IP三次挥手,四次断开(精简)
很多协议都是基于TCP/IP协议的基础之上进行工作的,可能我们了解这些原理近期看来并无实际作用,因为它不像如一些web服务器配置一样,配置了我就可以使用,就可以提供服务. 但是从我们长远发展角度来看, ...
- TCP/IP 三次握手,四次断开
TCP/IP 三次握手,四次断开 一.TCP报文格式 TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷 本. 下面是TCP报文格式图: 图 ...
- tcp/ip原理/三次握手/四次挥手
@ tcp/ip原理 1.1 tcp/ip三次握手 1.1.1 建立过程说明 a) 由主机A发送建立TCP连接的请求报文, 其中报文中包含seq序列号, 是由发送端随机生成的, 并且还将报文中SY ...
- 理解TCP三次握手/四次断开的必要性
1 TCP的三次握手与必要性 (1)三次握手图 (2)必要性:TCP通过三次握手建立可靠的(确保收到)的全双工通信. 1)第一次握手和第二次握手(ACK部分)建立了从客户端到服务器传送数据的可靠连接: ...
- TCP/IP协议(一)
TCP/IP是Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协 ...
- TCP/IP握手协议
转自:http://www.js123.net/t/n/n/2013/4/28/n_272.shtml 这篇介绍的也很棒:http://www.cnblogs.com/rootq/articles/1 ...
- TCP/IP笔记
TCP/IP 连接 三次握手 TCP/IP 四次分手 @TODO TIME_WAIT 状态 有三种状态可以进入此状态 1.由FIN-WAIT-2,双方不同时发起FIN,主动关闭的一方在完成自身发起的关 ...
- TCP\IP三次握手连接,四次握手断开分析
TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...
随机推荐
- python 爬虫与数据可视化--matplotlib模块应用
一.数据分析的目的(利用大数据量数据分析,帮助人们做出战略决策) 二.什么是matplotlib? matplotlib: 最流行的Python底层绘图库,主要做数据可视化图表,名字取材于MATLAB ...
- Linux 体系结构
Linux 体系结构 Linux 嵌入式系统的组成 层次结构图 bios 1.硬件检测 2.初始化系统设备 3.装入os 4.调os向硬件发出的指令 bsp 板级支持包 硬件相关 开发板原理图 开 ...
- c# asp.net mvc使用斑马GK888t打印机打印标签
前言 c#语言,asp.net mvc,南京都昌电子病历模板工具(类似word),斑马GK888t,打印手腕带和标签纸. 实现步骤为:在页面上显示一个或多个都昌模板工具,点击页面上的button,出现 ...
- 执行grunt命令报错 Cannot find module 'coffee-script'
Failed to list grunt tasks in yudian-frontend-salesplatform\Gruntfile.js: process finished with exit ...
- python--ModuleFoundError
python 模块导入错误: 1. 首先py文件名不能和导入的模块名相同 (我在学习matplotlib库的时候就把文件名设置成matplotlib 多次运行不成功) 2. 由于我电脑上只有numpy ...
- DataRow[]
datarow[]是datatable 的行数组集合,但是呢好像是不能直接初始化,只能是datarow[] rows = dt.select(condition);这样子.(也可能我才疏学浅没找到吧) ...
- Vue v-for循环添加表单v-model不重复变动的注意事项!
正常添加,v-model,修改所有循环会得到一样的结果! 定义一个users[]的数组,不要定义全局的user,而是要在Vue里面的方法里定义局部的变量添加.
- DAY10函数
函数 函数就是可以重复利用的工具 函数可以完成指定代码块,函数就是是存放代码块的容器 函数的有点: 1.避免出现重复冗余的代码 2.让程序代码结构更清晰增加可读性 3 定义函数的语法 1. 函数名:使 ...
- Python基础之变量作用域
一.分类: 二.变量名的查找规则: 三.局部变量: 四.全局变量: 五.global语句: 六.nonlocal语句: 七.基础代码: # 全局变量:当前.py文件内部都可访问 g01 = 100 d ...
- spring boot 集成 Redis
前提:你已经安装了Redis 1.创建一个spring boot 工程 2.pom 引入依赖:spring-boot-starter-data-redis <dependency> < ...