TCP三次握手 中讲述了序列号和建立连接,这一篇来说说释放连接

标志位

TCP首部中在属性标志位,和建立连接、释放连接有关,位于保留窗口字段中间,其中三个标识与断开连接有关。

  • ACK: acknowledgment(确认)--- 为1时,确认号字段才有效
  • RST: reset(重置)--- 为1时,表示tcp连接中出现问题,要释放连接并重新建立连接
  • FIN: finish(终止连接)--- 为1时,表示要求释放连接

还有两个属性序号确认号,与发送数据有关。

  • 序号(Sequence Number) --- TCP传输过程中每一个字节都有编号,建立连接后,序号表示TCP数据部分的第一个字节编号
  • 确认号(Acknowledgment Number)--- 期望对方下一次传过来的TCP数据部分的第一个字节编号

四次挥手

当数据发送完毕,客户端或者服务器一方发起释放连接请求时,会经历四个步骤,这里演示客户端发起。

① 客户端 —> 服务器:FIN=1, ACK=1,ack = v,seq = u(客户端请求释放连接,此次发送数据的序号是 u,数据长度为0,希望对方发送数据的编号为 v)

② 服务器 —> 客户端:ACK=1,seq = v,ack = u+1(服务端表示接收到释放连接的请求,此时发送数据的序号是 v,希望服务器下一次发送数据以 u+1 开始,因为客户端上一条请求中序号是u,希望服务器响应数据以v开始)

③ 服务器 —> 客户端:FIN=1, ACK=1,seq = w,ack = u+1(服务端请求释放连接,此时发送数据的序号是 w,数据长度为0,希望对方下一次发送数据从 u+1 开始)

④ 客户端 —> 服务器:ACK=1,seq = u+1,ack = w+1(客户端接收到服务器也希望断开请求的消息,同时发送 u+1 的数据,希望对方发送数据为上一次客户端数据 w+1)

状态变化

这里发送方和接收方各自都有一些状态。

  • ESTABLISHED:表示连接已经建立
  • FIN-WAIT-1:表示想主动关闭连接,向对方发送了FIN报文,此时进入到FIN-WAIT-1状态
  • CLOSE-WAIT:表示在等待关闭,当对方发送FIN给自己,自己会回应一个ACK报文给对方,此时则进入到CLOSE-WAIT状态,在此状态下,需要考虑自己是否还有数据要发送给对方,如果没有,发送FIN报文给对方
  • FIN-WAIT-2:只要对方发送ACK确认后,主动方就会处于FIN-WAIT-2状态,然后等待对方发送FIN报文
  • LAST-ACK:被动关闭一方在发送FIN报文后,最后等待对方的ACK报文,当收到ACK报文后,即可进入CLOSED状态了
  • TIME-WAIT:表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可进入CLOSED状态
  • CLOSED:关闭状态

以上是完整四次挥手流程,但我们在抓包的时候,也有可能会看到三次挥手

当服务器接收到客户端的FIN时,如果服务器后面没有数据要发给客户端时,服务器有可能把第2、3次挥手合并(同时带FIN标志和ACK标志的报文),相当于同时告诉客户端两件事

  • 已经知道client没有数据要发
  • server已经没有数据要发

此时FIN-WAIT-1状态就不经过FIN-WAIT-2,直接到TIME-WAIT

为什么要四次挥手

四次挥手中存在客户端和服务器分别 发起断开请求确认收到对方的断开请求,那这里的四次是不是可以简化成两次,只要一方发起,另一方确认就行。

这样是不可以的,因为TCP是全双工通信,一方发送关闭请求,仍然可以继续接收消息。

① 客户端 —> 服务器:客户端告诉服务器没有数据要发送,但是客户端还可以接收

② 服务器 —> 客户端:服务器已经知道客户端没有数据发送,但是服务器仍可以发送

③ 服务器 —> 客户端:服务器告诉客户端,服务器没有数据要发送了

④ 客户端 —> 服务器:服务器已经知道客户端没有数据要发送,随后正式断开整个TCP连接

经过了四次消息的交互之后,才能完全确认双方都已经没有数据要发送。

2ML

MSL:Maximum Segment Lifetime,最大分段生存期,MSL是TCP报文在Internet上的最长生存时间,一般是2分钟

客户端第四次挥手,发送ACK的确认报文后,不会马上进入 CLOSED 关闭状态,而是会在TIME-WAIT等待2ML的时间,是为了防止本次连接中产生的数据包误传到下一次连接中(因为本次连接中的数据包都会在2MSL时间内消失了)

因为可能存在这样的情况:如果网络原因,服务器没有收到ack,那么服务器会重发FIN,如果客户端发送了一次ACK后就马上进入CLOSED阶段,那么客户端收不到服务器的FIN。 如果此时客户端的新应用分配了同一个端口号,那么新的应用程序收到服务器传来FIN的报文,以为是要请求关闭,那么会马上会释放连接。

抓包

抓包工具可以看到释放连接时的四次挥手

使用 netstat 命令可以看到连接状态

以上就是 释放连接与状态变化的内容 , 更多有关 前端网络协议 的内容可以参考我其它的博文,持续更新中~

TCP四次挥手会经历这么多状态的更多相关文章

  1. TCP四步挥手的各种状态转换图

    对于TCP四步挥手时的各种状态转换,网上有很多资料.但是有很多描述不是很容易理解,甚至是描述错误,不如这篇文章里http://www.cnblogs.com/Jessy/p/3535612.html# ...

  2. TCP四次挥手

    TCP 四次挥手      TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake).客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close ...

  3. TCP为什么是三次握手,为什么不是两次或者四次 && TCP四次挥手

    这是一个很有意思的问题~ 首先,我们要知道TCP是全双工的,即客户端在给服务器端发送信息的同时,服务器端也可以给客户端发送信息.而半双工的意思是A可以给B发,B也可以给A发,但是A在给B发的时候,B不 ...

  4. Java网络编程学习A轮_03_抓包分析TCP四次挥手

    参考资料: http://www.jellythink.com/archives/705 示例代码: https://github.com/gordonklg/study,socket module ...

  5. TCP四次挥手断开连接详解

    TCP四次挥手. 数据传输结束后,通信的双方都可释放连接.现在A和B都处于ESTABLISHED状态.A的应用程序先向TCP发出连接释放报文段,主动关闭TCP连接.A把连接释放报文段的首部FIN置为1 ...

  6. 计算机网络(五),TCP四次挥手

    目录 1.TCP四次挥手详情 2.为什么会有TIME-WAIT状态 3.为什么需要四次握手才能断开连接 4.服务器出现大量CLOSE_WAIT的原因 五.TCP四次挥手 1.TCP四次挥手详情 (1) ...

  7. 被面试官问懵:TCP 四次挥手收到乱序的 FIN 包会如何处理?

    摘要:收到个读者的问题,他在面试的时候,被搞懵了,因为面试官问了他这么一个网络问题. 本文分享自华为云社区<TCP 四次挥手收到乱序的 FIN 包会如何处理?>,作者:小林coding . ...

  8. 详解TCP四次挥手(断开TCP连接过程)

    在讲述TCP四次挥手,即断开TCP连接的过程之前,需要先介绍一下TCP协议的包结构. TCP协议包结构: 这里只对涉及到四次挥手过程的字段做解释 (1) 序号(Sequence number) 我们通 ...

  9. 计算机网络之tcp四次挥手

    TCP的四次挥手(Four-Way Wavehand)1.前言对于"三次握手"我们耳熟能详,因为其相对的简单.但是,我们却不常听见“四次挥手”,就算听过也未必能详细地说明白它的具体 ...

  10. TCP三次握手连接和TCP四次挥手及大量TIME_WAIT解决方法:

    1.TCP建立连接,三次握手 建立的TCP连接可靠的连接,必须经过三次握手建立连接才能正式通信彼此传输数数据. 客户端请求服务端建立连接 第一次握手:客户给服务发送一个请求报文SYN, 客户端的状态置 ...

随机推荐

  1. Extjs4 Tree Grid 综合示例(展开、编辑列、获取数据)

    用json数据模拟后端传回来的结果,Extjs tree支持两种类型的结构,一种是带children属性的嵌套式的数据,一种是扁平的,每条记录带pid的数据,带pid的添加配置项可以自动解析成树形结构 ...

  2. 2020-08-11:一颗现代处理器,每秒大概可以执行多少条简单的MOV指令,有哪些主要的影响因素?

    福哥答案2020-08-11: [知乎答案](https://www.zhihu.com/question/413389230)MOV 指令将源操作数复制到目的操作数,是最基本的指令.首先就和CPU主 ...

  3. 2022-07-14:以下go语言代码输出什么?A:1;B:3;C:4;D:编译错误。 package main import ( “fmt“ ) func main() { a

    2022-07-14:以下go语言代码输出什么?A:1:B:3:C:4:D:编译错误. package main import ( "fmt" ) func main() { a ...

  4. 2021-01-19:mysql中,一张表里有3亿数据,未分表,其中一个字段是企业类型,企业类型是一般企业和个体户,个体户的数据量差不多占50%,根据条件把个体户的行都删掉。请问如何操作?

    2021-01-19:mysql中,一张表里有3亿数据,未分表,其中一个字段是企业类型,企业类型是一般企业和个体户,个体户的数据量差不多占50%,根据条件把个体户的行都删掉.请问如何操作?福哥答案20 ...

  5. 2021-04-29:给定一个数组 arr,代表一排有分数的气球。每打爆一个气球都能获得分数,假设打爆气 球 的分数为 X,获得分数的规则如下: 1)如果被打爆气球的左边有没被打爆的气球,找到离被打爆

    2021-04-29:给定一个数组 arr,代表一排有分数的气球.每打爆一个气球都能获得分数,假设打爆气 球 的分数为 X,获得分数的规则如下: 1)如果被打爆气球的左边有没被打爆的气球,找到离被打爆 ...

  6. save() prohibited to prevent data loss due to unsaved related object 'item_n

    问题描述: save() prohibited to prevent data loss due to unsaved related object 'item_no 原因分析: 原来的目的是保存数据 ...

  7. vue 版本查看

    如何查看vue版本号? 方法1.全局查看vue版本号 npm info vue方法2.局部(当前项目)查vue版本号 npm list vue version方法3.此外还可以通过 package.j ...

  8. Python Numpy 切片和索引(高级索引、布尔索引、花式索引)

    张量(Tensor).标量(scalar).向量(vector).矩阵(matrix) Python Numpy 切片和索引(高级索引.布尔索引.花式索引) Python NumPy 广播(Broad ...

  9. JS加载机制

    做开发多年后发现自己思维任然只定位在功能的实现:忽略了很多代码最终的实现,加载机制等 那我们接下来就借助几篇博客来理理天天看见的js:理理他究竟是怎么过执行的 一.代码检测 首先浏览器会对所有js 进 ...

  10. Gitlab Registries

    在项目开发和部署过程中,我们常常需要一套私有仓库,比如 Code Repository.Package Repository,Docker Registry 等. Code Repository:在 ...