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种标 ...
随机推荐
- url.cn短网址批量缩短开发接口
https://www.showapi.com/api/view/1728 //md5签名方式--非简单签名 <?php header("Content-Type:text/html; ...
- JAVA基础复习与总结<九> 线程的基本概念_Thread继承创建线程
多线程 一.线程的概念 1.1 程序.进程.线程 程序:Program 是一个静态的概念 进程:Process 是一个动态的概念 进程是程序的一次动态执行过程,占用特定的地址空间. 每个进程都是独立的 ...
- 关机,重启BAT命令
关机命令shutdown -s -t 重启命令 shutdown -r -t
- Handler Timer TimerTask ScheduledExecutor 循环任务解析
使用Handler执行循环任务 private Handler handler = new Handler(); private int mDelayTime = 1000; private Runn ...
- MyBatis3系列__06查询的几点补充
关于查询的一点补充: 当查询部门信息时,希望查询该部门下的所有员工,下面会采取两种方式实现: 1.联合查询 public Department getDeptWithEmpById(Integer i ...
- c++标准---for循环新用法
贪吃蛇游戏的c++版本,从GitHub上clone下来的,在startinterface.cpp文件中有如下代码: void StartInterface::PrintText() { for ( ...
- vue2.0 如何自定义组件(vue组件的封装)
一.前言 之前的博客聊过 vue2.0和react的技术选型:聊过vue的axios封装和vuex使用.今天简单聊聊 vue 组件的封装. vue 的ui框架现在是很多的,但是鉴于移动设备的复杂性,兼 ...
- angular学习笔记(三)
1.安装npm install --save @angular/material@2.0.0-beta.72.安装http://chrome-extension-downloader.com安装aug ...
- ASP.NET Core知多少(7):对重复编译说NO -- dotnet watch
ASP.NET Core知多少系列:总体介绍及目录 1. 引言 我们一般的开发过程,就是编码-->编译-->运行-->调试-->定位问题--->修改代码-->编译- ...
- 算法与数据结构(十) 二叉排序树的查找、插入与删除(Swift版)
在上一篇博客中,我们主要介绍了四种查找的方法,包括顺序查找.折半查找.插入查找以及Fibonacci查找.上面这几种查找方式都是基于线性表的查找方式,今天博客中我们来介绍一下基于二叉树结构的查找,也就 ...