经过前面对TCP连接管理的介绍,我们本小节通过TCP连接管理的状态机来总结一下看看TCP连接的状态变化

一、TCP状态机整体状态转换图(截取自第二版TCPIP详解)

二、TCP连接建立和终止过程中状态迁移总结

下面我们总结一下前面介绍过的连接建立方式和终止过程中client端和server端的状态切换

1、三次握手

client:CLOSED -> SYN_SENT -> ESTABLISHED

server:CLOSED -> LISTEN -> SYN_RCVD ->ESTABLISHED

2、四次挥手

client:ESTABISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

server:ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

3、TCP同开

client:CLOSED->SYN_SENT->SYN_RCVD->ESTABLISHED

server:CLOSED->SYN_SENT->SYN_RCVD->ESTABLISHED

4、TCP同关

client:ESTABLISHED->FIN_WAIT_1->CLOSING->TIME_WAIT->CLOSED

server:ESTABLISHED->FIN_WAIT_1->CLOSING->TIME_WAIT->CLOSED

5、三次挥手

client:ESTABISHED->FIN_WAIT_1->TIME_WAIT->CLOSED

server:ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

注意此处server侧内部虽然经历了ESTABLISHED->CLOSE_WAIT的状态转换,但是实际在由ESTABLISHED状态转换到CLOSE_WAIT状态的过程中并没有发送ACK包,ACK实际是随着CLOSE_WAIT->LAST_ACK状态切换过程中的FIN包一起发送的。可以观察前面文章wireshark抓包示例图。

三、一些状态说明

1、TIME_WAIT状态

TIME_WAIT状态也叫做2MSL等待状态。MSL(Maximum Segment Lifetime)中文可以译为报文最大生存时间。TIME_WAIT则是指Active Opener在连接结束前要等待2MSL的时间,有时这个状态也叫做timed wait。RFC793指定MSL时长为2分钟,但是在实现上可能会使用其他值。实际上在active close的时候,部分场景下linux会把FIN_WAIT_2作为TIME_WAIT的一个子状态。linux中net.ipv4.tcp_fin_timeout可以设置FIN_WAIT_2定时器的值。

TIME_WAIT主要由两个作用一个是给active closer重新发送ACK报文的机会。当active closer发送完最后一个ACK后,继续保留2MSL时间,这样如果passive closer没有收到最后一个ACK而重发FIN的情况下,可以让active closer机会重新发送ACK报文。另外一个作用则是同一个四元组(源ip、源端口、目的IP、目的端口)标识的连接一般只有在TIME_WAIT结束后才能重新建立。但是有两种例外情况,一种是新连接SYN中的seq系列号比之前相同连接实例相同方向的最大系列号还要大(RFC1122),或者通过时间戳的扩展可以区分出这同一个连接的不同实例(RFC6191)。

如果一台主机在TIME_WAIT状态下崩溃并且快速重启,然后以之前的四元组建立一个相同的连接,如果这个过程时间够短,那么有可能之前连接实例的数据包错误的被接收并当作有效的数据包。为了保护这种场景,RFC793要求一个主机在重启后需要等待MSL时间后在创建新的TCP连接,这个就是平静时间(quiet time)。因为大多数主机重启需要的时间可能都比MSL长,因此主机在实现上可能并不会真的等待MSL时间在建立TCP连接。另外再次说一下应用层如果对数据完整性要求比较高,需要自己添加校验。

2、FIN_WAIT_2状态

在实现上,如果Active Closer的应用程序是彻底关闭TCP连接(调用close接口),而不是指示半关TCP连接(shutdown)接口,那么这个endpoint并不会一直停留在FIN_WAIT_2状态,而是会设置一个定时器,一旦定时器超时,这个连接还没有收到数据包,那么这个endpoint会直接进入CLOSED状态。这个定时器的值同样受net.ipv4.tcp_fin_timeout控制。

补充说明:

1、从LISTEN状态切换到SYN_SENT状态,协议是支持的,但是在linux实现上是不支持的

2、为了支持TFO,目前TCP内部实际上是12种TCP状态,新添加了一个NEW_SYN_RCVD用于传统的tcp连接,普通连接在收到三次握手最后的ACK的时候,会从NEW_SYN_RCVD切换到SYN_RCVD然后在切换到ESTABLISHED。

https://patchwork.ozlabs.org/patch/449704/

3、用于支持容器间TCP迁移的tcp repair模式,TCP在不发送数据包的情况下也可以直接由CLOSED切换到ESTABLISHED,但是这个属于实现层面的状态切换。

https://lwn.net/Articles/495304/

https://www.youtube.com/watch?v=IkH7p2jmxok

4、Linux下TIME-WAIT处理参考tcp_timewait_state_process,其中RFC1122和RFC6191给出的两种在TIME-WAIT下建立同一个连接的新实例的场景,linux都已实现。另外要说明一下的是当使用close系统调用关闭TCP连接的时候,最后的FIN-WAIT2在linux内部实际是作为TIMEWAIT的一个子状态存在的。

TCP系列07—连接管理—6、TCP连接管理的状态机的更多相关文章

  1. TCP系列11—重传—1、TCP重传概述

    在最开始介绍TCP的时候,我们就介绍了TCP的三个特点,分别是面向连接.可靠.字节流式.前面内容我们已经介绍过了TCP的连接管理,接下来的这部分内容将会介绍与TCP可靠性强关联的TCP重传. 很多网络 ...

  2. TCP系列08—连接管理—7、TCP 常见选项(option)

    一.TCP选项概述 在前面介绍TCP头的时候,我们说过tcp基本头下面可以带有tcp选项,其中有些选项只能在连接过程中随着SYN包发送,有些可以延后.下表汇总了一些tcp选项 其中我标记为红色的部分是 ...

  3. TCP系列05—连接管理—4、TCP连接的ISN、连接建立超时及TCP的长短连接

    一.TCP连接的ISN         之前我们说过初始建立TCP连接的时候的系列号(ISN)是随机选择的,那么这个系列号为什么不采用一个固定的值呢?主要有两方面的原因 防止同一个连接的不同实例(di ...

  4. TCP系列02—连接管理—1、三次握手与四次挥手

    一.TCP连接管理概述 正如我们在之前所说TCP是一个面向连接的通信协议,因此在进行数据传输前一般需要先建立连接(TFO除外),因此我们首先来介绍TCP的连接管理. 通常一次完整的TCP数据传输一般包 ...

  5. TCP系列03—连接管理—2、TCP连接的同时打开和同时关闭

    在前面的内容中我们介绍了TCP连接管理中最常见的三次握手方式和四次挥手的方式.但是有可能A和B两端同时执行主动打开并连接对方或者同时执行主动关闭连接(尽管发生这种情况的可能性比较低低),这个时候的流程 ...

  6. TCP系列04—连接管理—3、TCP连接的半打开和半关闭

    在前面部分我们我们分别介绍了三次握手.四次挥手.同时打开和同时关闭,TCP连接还有两种场景分别是半打开(Half-Open)连接和半关闭(Half-Close)连接.TCP是一个全双工(Full-Du ...

  7. SQL Server 连接问题-TCP/IP

    原文:SQL Server 连接问题-TCP/IP 出自:http://blogs.msdn.com/b/apgcdsd/archive/2012/02/24/ms-sql-server-tcp-ip ...

  8. 小tips:TCP的三次握手、长连接、 短连接、 SPDY 协议

    当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次握手的,而释放则需 ...

  9. 异数OS TCP协议栈测试(三)--长连接篇

    异数OS TCP协议栈测试(三)--长连接篇 本文来自异数OS社区 github:   异数OS-织梦师(消息中间件)群: 476260389 异数OS TCP长连接技术简介 说起长连接,则首先要谈对 ...

随机推荐

  1. collections.Counter类统计列表元素出现次数

    # 使用collections.Counter类统计列表元素出现次数 from collections import Counter names = ["Stanley", &qu ...

  2. Java : Spring基础 IOC

    使用 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml" ...

  3. Struts2+EasyUI+Hibernate小实例

    概述 这个实例主要是前台数据到后台数据的传递和后台数据到前台数据的传递,完成数据的新增,以及对新增数据的展示.下面是详细的过程: Hibernate(数据库部分) 这里只是数据库的连接和数据库实体与物 ...

  4. python学习笔记:第7天 深浅拷贝

    目录 1. 基础数据类型补充 2. set集合 3. 深浅拷贝 1. 基础数据类型补充 (1)join方法 join方法是把一个列表中的数据进行拼接,拼接成字符串(与split方法相反,split方法 ...

  5. ecshop跨站漏洞详情及修补网站漏洞

    ecshop目前最新版本为4.0,是国内开源的一套商城系统,很多外贸公司,以及电商平台都在使用,正因为使用的人数较多,很多攻击者都在挖掘该网站的漏洞,就在最近ecshop被爆出高危漏洞,该漏洞利用跨站 ...

  6. Grep/find查找文件

    1. 查找secret 函数所在的文件位置grep -rn secret * grep -rn "secret" * 2. find 查找当前目录下,比while2 时间新并且名字 ...

  7. Lingo基本操作

    目录 Lingo基本操作 前言 一.Lingo基本运算符 1.1 算术运算符 1.2 逻辑运算符 1.3 关系运算符 二.函数 2.1 标准数学函数 2.2 集循环函数 三.待更新 Lingo基本操作 ...

  8. 常见java异常英语词汇(一)

    denied   /dɪ'naɪəd/    adj 拒签  v 拒绝

  9. Installing python-ldap in Ubuntu

    These are the steps to be followed to install python-ldap in Ubuntu. At first, sudo apt-get install ...

  10. Linux 7.4配置VSFTP服务器

    vsftpd(very secure ftp daemon,非常安全的FTP守护进程)是一款运行在Linux操作系统上的FTP服务程序,不仅完全开源而且免费,此外,还具有很高的安全性.传输速度,以及支 ...