TCP协议状态转换详解

news/2024/5/17 18:51:06 标签: TCP

、三次握手和四次挥手

1、建立连接(三次握手)

  (1)服务器会处于listen状态,客户端发送一个带SYN标志的TCP报文到服务器。

  (2)服务器端回应客户端的请求,这是三次握手中的第2个报文,这个报文同时带SYN标志和ACK标志。

          因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯。

  (3)客户必须再次回应服务段一个ACK报文,这个时候两端就处于已经建立连接

 

2、终止连接(四次握手)

   由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是:当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

  (1) 客户端发送一个FIN,用来关闭客户到服务器的数据传送。

  (2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。

  (3) 服务器关闭客户端的连接,发送一个FIN给客户端 。

  (4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1。

二、TCP协议状态解析

 

------------------------------------------------------------------------发起握手阶段---------------------------------------------------------------------------

CLOSED: 表示初始状态。

 

LISTEN: 表示服务器端的某个SOCKET处于监听状态,可以接受连接。

 

SYN_RCVD: 表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。

 

SYN_SENT: 这个状态与SYN_RCVD遥相呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

 

ESTABLISHED:表示连接已经建立,这是双方进行正常通信所处的状态。

-------------------------------------------------------------------------主动关闭阶段--------------------------------------------------------------------------

 

FIN_WAIT_1:本地发送FIN(用于结束连接的)数据包后即可进入该状态,等待对方的应答。一般一端发送完其所要发送的数据后,即可发送FIN数据包,此时发送通道被关闭,但仍可继续接受远端发送的数据包。在接受到远端发送的对于FIN数据包的ACK应答后,将进入FIN_WAIT_2状态。

 

FIN_WAIT_2:进入该状态表示本地已经接收到远端发送的对于本地之前发送的FIN数据包的ACK应答。进入该状态后,本地仍然可以继续接受远端发送给本地的数据包。在接受到远端发送的FIN数据包后(表示远端也已经发送完数据),本地将发送一个应答数据包,并进入TCP_TIME_WAIT状态。TIME_WAIT状态存在的时间被称为2MSL时间,这一方面是为避免本地发送的应答数据包丢失,另一方面避免一个新创建的套接字接收到旧套接字中遗留的数据包。

其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示(主动关闭阶段)等待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET立即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态。当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。

 

FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。

 

TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL(2倍报文段寿命)后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

该转状态被称为2MSL等待状态。如果在此期间接收到远端发送的FIN数据包,则表示之前在TCP_FIN_WAIT_2状态发送的ACK应答数据包在传输中丢失或者长时间被延迟,从而造成了远端重新发送了FIN数据包,此时重复ACK应答数据包。一旦2MSL时间到期,则将进入TCP_CLOSED状态,即完成关闭操作。

 

CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

------------------------------------------------------------------------被动关闭阶段---------------------------------------------------------------------------

 

CLOSE_WAIT: 当对方率先发送FIN报文给自己,本地系统毫无疑问地会回应一个ACK报文给对方,此时套接字状态从ESTABLISED进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。

该状态存在于被动关闭(后关闭)的一端。当接收到远端发送的FIN数据包后,本地发送一个ACK应答数据包,并将该套接字状态从ESTABLISED设置为CLOSE_WAIT。本地可以继续向远端发送数据包,在发送完所有的数据后,本地将发送一个FIN数据包关闭本地发送通道,并将状态设置为LAST_ACK状态,等待远端对FIN数据包的应答数据包。

 

LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。

三、状态统计

统计TCP状态:netstat -ant | awk '/^tcp/{++State[$NF]} END {for (key in State) print key,State[key]}'


http://www.niftyadmin.cn/n/1638840.html

相关文章

Mqtt Qos 深度解读

1.QoS含义 : Quality of Service,服务质量 2.作用域 发布者的Qos 订阅者的Qos 3.等级与作用 level 0:最多一次的传输 level 1:至少一次的传输,(鸡肋) level 2: 只有一次的传输 4.交互过程 qos0 对于qos1而言&a…

HashMap哈希算法引出的求余%和与运算转换问题

1、引出问题 在前面讲解HashMap 的源码实现时&#xff0c;有如下几点&#xff1a; ①、初始容量为 1<<4&#xff0c;也就是24 16 ②、负载因子是0.75&#xff0c;当存入HashMap的元素占比超过整个容量的75%时&#xff0c;进行扩容&#xff0c;而且在不超过int类型的范围…

Elasticsearch:跨集群数据迁移之离线迁移

跨集群数据迁移 用户在腾讯云上自建的ES集群或者在其它云厂商购买的ES集群&#xff0c;如果要迁移至腾讯云ES&#xff0c;用户可以根据自己的业务需要选择适合自己的迁移方案。如果业务可以停服或者可以暂停写操作&#xff0c;可以参考离线迁移的四种方案。 离线迁移 离线迁…

mysql视图和临时表的区别

视图 视图是由从数据库的基本表中选出来的数据组成的逻辑窗口&#xff0c;它与基本表不同的是&#xff0c;视图是一个虚表。数据库中只存放视图的定义&#xff0c;而不存放视图包含的数据&#xff0c;这些数据仍存放在原来的基表中。所以基表中的数据如果发生改变&#xff0c;…

Hive学习实例

正文 一、求单月访问次数和总访问次数 1、数据说明 数据字段说明 用户名&#xff0c;月份&#xff0c;访问次数 数据格式 A,2015-01,5 A,2015-01,15 B,2015-01,5 A,2015-01,8 B,2015-01,25 A,2015-01,5 A,2015-02,4 A,2015-02,6 B,2015-02,10 B,2015-02,5 A,2015-03,16 A,2…

hive读取Hbase的数据

1、文档(不会的直接找文档最方便) HBaseIntegration 2、拷贝jar文件 2.1 将Hbase/bin目录下面文件拷贝到Hive/bin目录下 cd /home/hbase/lib cp ./* /home/hive/lib 2.2 把Hive的lib目录下面的hive-hbase-handler-0.13.1.jar拷贝到Hbase的lib目录下面 cp /home/hive/lib/h…

Kafka数据到Hdfs

找时间总结整理了下数据从Kafka到Hdfs的一些pipeline&#xff0c;如下 1> Kafka -> Flume –> Hadoop Hdfs 常用方案,基于配置,需要注意hdfs小文件性能等问题. GitHub地址: https://github.com/apache/flume 2> Kafka -> Kafka Hadoop Loader ->Hadoop …

揭秘阿里百亿级云客服实时分析架构演进之路

淘宝、天猫每天有上亿个不同的买卖家进行对话&#xff0c;产生百亿条聊天记录。对客服聊天记录的实时分析是实现智能客服的基础。本文主要分享云客服的整体架构&#xff0c;包括实时分析的场景、架构、技术难点&#xff0c;以及为何要从 NoSQL 迁移时序数据库和使用心得。 网…