经过前面对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. day 14 内置函数二

    1.昨日的补充 reversed    翻转, 将一个序列翻转,返回翻转序列的迭代器 lst = ["河南话", "四川话", "东北", ...

  2. 大数据学习--day11(抽象类、接口、equals、compareTo)

    抽象类.接口.equals.compareTo 什么是抽象方法  ?     区分于正常的方法       1.使用了 abstract 修饰符          该修饰符修饰方法 则该方法就是抽象方 ...

  3. Java开发小技巧(五):HttpClient工具类

    前言 大多数Java应用程序都会通过HTTP协议来调用接口访问各种网络资源,JDK也提供了相应的HTTP工具包,但是使用起来不够方便灵活,所以我们可以利用Apache的HttpClient来封装一个具 ...

  4. sql server 常用sql语句

    --删除约束 alter table productInfo drop constraint 约束名称 --删除列alter table productInfo drop column 列名 --添加 ...

  5. JAVA基础 - 类的构造与实例化

    一个简单的demo,主要运用: 抽象类,类的继承 类的实例化,构造函数 @Override重写父类方法 package week4; abstract class Person { void show ...

  6. MFC实现http连接、发送和接收数据

    #include <afxinet.h> // 设置超时 CInternetSession session; session.SetOption(INTERNET_OPTION_CONNE ...

  7. easyui设置行的背景色

    var arr = new Array(3000082, 3000095); self.itemGrid.datagrid({ rowStyler: function (index, row) { f ...

  8. BINARYSEARCH有り無しのパフォーマンスの違い

    BINARY SEARCHを使用したパフォーマンス検証を行ってみた.この例では.BKPFが約1万件.BSEGが約3万件になるよう調整している.また.SQLの実行に係る時間は無視する事にする. サンプル ...

  9. 三、并行流与串行流 Fork/Join框架

    一.并行流概念: 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流. java8中将并行进行了优化,我们可以很容易的对数据进行并行操作.Stream API可以声明性的通过pa ...

  10. jsp传递参数的四种方法

    1.form表单 2.request.setAttribute();和request.getAttribute(); 3.超链接:<a herf="index.jsp"?a= ...