首页 > 其他分享 >tcp连接全过程各种状态详解

tcp连接全过程各种状态详解

时间:2024-01-29 16:01:42浏览次数:30  
标签:状态 报文 tcp TCP 详解 全过程 FIN 连接 WAIT

// from netinet/tcp.h

enum

{

  TCP_ESTABLISHED = 1, // 代表一个打开的连接

  TCP_SYN_SENT, // 再发送连接请求后等待匹配的连接请求(客户端)

  TCP_SYN_RECV, // 再收到和发送一个连接请求后等待对方对连接请求的确认(服务器)

  TCP_FIN_WAIT1, // 等待远程TCP连接中断请求,或先前的连接中断请求的确认

  TCP_FIN_WAIT2, // 从远程TCP等待连接中断请求

  TCP_TIME_WAIT, // 等待足够的时间以确保远程TCP接收到连接中断请求的确认

  TCP_CLOSE,

  TCP_CLOSE_WAIT, // 等待从本地用户发来的连接中断请求

  TCP_LAST_ACK, // 等待原来的发向远程TCP的连接中断请求的确认

  TCP_LISTEN, // 侦听来自远方的TCP端口的连接请求

  TCP_CLOSING  // 等待远程TCP对连接中断的确认 /* now a valid state */

};

 

主动端可能出现的状态:FIN_WAIT1、FIN_WAIT2、CLOSING、TIME_WAIT

被动端可能出现的状态:CLOSE_WAIT LAST_ACK

 

客户端的状态可以用如下的流程来表示:

CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

服务器的状态可以用如下的流程来表示:

CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

(1)主动端出现大量的FIN_WAIT1时需要注意网络是否畅通、出现大量的FIN_WAIT2需要仔细检查程序为何迟迟收不到对端的FIN(可能是主动方或者被动方的bug)、出现大量的TIME_WAIT需要注意系统的并发量/socket句柄资源/内存使用/端口号资源等。

(2)被动端出现大量的 CLOSE_WAIT 需要仔细检查为何自己迟迟不愿调用close关闭连接(可能是bug,socket打开用完没有关闭)

三次握手如下图:

建立连接时的状态变迁

一开始,建立连接之前服务器和客户端的状态都为CLOSED。服务器创建socket后开始监听,变为LISTEN状态。客户端请求建立连接,向服务器发送SYN报文,客户端的状态变为SYN_SENT。服务器收到客户端的报文后向客户端发送ACK和SYN报文,此时服务器的状态变为SYN_RCVD。然后,客户端收到ACK、SYN,就向服务器发送ACK,客户端状态变为ESTABLISHED,服务器收到客户端的ACK后也变为ESTABLISHED。此时,3次握手完成,连接建立!

 

tcp连接建立(tcp三握手)

TCP连接的建立采用客户-服务器模式:主动发起连接建立的应用进程叫做客户,被动等待连接建立的应用进程叫做服务器。

 

连接建立阶段:

 

第一次握手:客户端的应用进程主动打开,并向服务端发出请求报文段。其首部中:SYN=1,seq=x。

 

第二次握手:服务器应用进程被动打开。若同意客户端的请求,则发回确认报文,其首部中:SYN=1,ACK=1,ack=x+1,seq=y。

 

第三次握手:客户端收到确认报文之后,通知上层应用进程连接已建立,并向服务器发出确认报文,其首部:ACK=1,ack=y+1。当服务器收到客户端的确认报文之后,也通知其上层应用进程连接已建立。

 

在这个过程中,通信双方的状态如下图,其中CLOSED:关闭状态、LISTEN:收听状态、SYN-SENT:同步已发送、SYN-RCVD:同步收到、ESTAB-LISHED:连接已建立

至此,TCP连接就建立了,客户端和服务器可以愉快地玩耍了。只要通信双方没有一方发出连接释放的请求,连接就将一直保持。

 

四次挥手如下图:

断开连接时的状态变迁

由于tcp连接是全双工的,断开连接会比建立连接麻烦一点点。客户端先向服务器发送FIN报文,请求断开连接,其状态变为FIN_WAIT1。服务器收到FIN后向客户端发生ACK,服务器状态变为CLOSE_WAIT。客户端收到ACK后就进入FIN_WAIT2状态。此时连接已经断开了一半了。如果服务器还有数据要发送给客户端,就会继续发送。直到发完了,就发送FIN报文,此时服务器进入LAST_ACK状态。客户端收到服务器的FIN后,马上发送ACK给服务器,此时客户端进入TIME_WAIT状态,再过了2MSL长的时间后进入CLOSED状态。服务器收到客户端的ACK就进入CLOSED状态。

 

至此,还有一个状态没有提及:CLOSING状态。CLOSING状态表示客户端发生了FIN,但没有收到服务器的ACK,却收到了服务器的FIN。这种情况发生在服务器发送的ACK丢包的时候,因为网络传输有时会有意外。

 

tcp连接终止协议*(tcp四挥手)

 

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

 

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

 

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

 

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

 

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

 

各个状态详解:

CLOSED:

这个没什么好说的了,表示初始状态。

LISTEN:

这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。

SYN_RCVD:

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

什么是SYN Flood攻击?

SYN Flood (SYN洪水) 是种典型的DoS (Denial of Service,拒绝服务) 攻击。效果就是服务器TCP连接资源耗尽,停止响应正常的TCP连接请求。

TCP SYN Flood是一种常见,而且有效的远端(远程)拒绝服务(Denial of Service)攻击方式,它通过一定的操作破坏TCP三次握手建立正常连接,占用并耗费系统资源,使得提供TCP服务的主机系统无法正常工作。由于TCP SYN Flood是透过网路底层对服务器Server进行攻击的

这个攻击的解决方法如下:

1、增加未完成连接队列(q0)的最大长度。

echo 1280>/proc/sys/net/ipv4/tcp_max_syn_backlog

2、启动SYN_cookie。

echo 1>/proc/sys/net/ipv4/tcp_syncookies

这些是被动的方法,治标不治本。而且加大了服务器的负担,但是可以避免被拒绝攻击(只是减缓)

治本的方法是在防火墙上做手脚。但是现在能在一定程度上防住syn flood攻击的防火墙都不便宜。并且把这个命令加入”/etc/rc.d/rc.local”文件中

3、iptables的设置

防止同步包洪水(Sync Flood)

# iptables -A FORWARD -p tcp –syn -m limit –limit 1/s -j ACCEPT

SYN_SENT:

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

ESTABLISHED:

这个容易理解了,表示连接已经建立了。

FIN_WAIT_1:

这个状态要好好解释一下,其实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连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接这就是著名的半关闭的状态了,这是在关闭连接时,客户端和服务器两次握手之后的状态。在这个状态下,应用程序还有接受数据的能力,但是已经无法发送数据,但是也有一种可能是,客户端一直处于FIN_WAIT_2状态,而服务器则一直处于WAIT_CLOSE状态,而直到应用层来决定关闭这个状态

TIME_WAIT:

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

CLOSING:

这里先说一下另一种状态(同时打开)

 

RST是另一种关闭连接的方式,应用程序应该可以判断RST包的真实性,即是否为异常中止。而同时打开和同时关闭则是两种特殊的TCP状态,发生的概率很小。

下面说closing状态

 

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

比如建立

CLOSE_WAIT:

这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是查看你是否还有数据发送给对方,如果没有的话,那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。

LAST_ACK:

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

 

转载自:tcp连接全过程各种状态详解  https://zhuanlan.zhihu.com/p/474669610

 

标签:状态,报文,tcp,TCP,详解,全过程,FIN,连接,WAIT
From: https://www.cnblogs.com/tryst/p/17994723

相关文章

  • HTML5 WebSocket 详解及使用
    WebSocket没用过的同学,听上去,可能觉得很难,其实很简单,本章讲解了WebSocket基本信息,以及附有代码例子WebSocket是什么?WebSocket是HTML5提供的一种在单个TCP连接上进行全双工通讯的协议。(双向通信协议)WebSocket的作用?实现客户端与服务器之间的双向通信,允许服务端主动......
  • 关于Linux内核4.12之前版本中, tcp_tw_recycle开启后NAT环境总是出问题的分析
     问题出现的场景很简单,nat网关下,有几台服务器,需要访问企业内部的某个的API服务器,API服务器上rcycle设置为1(4.12内核版本之前有这个设置,之后这个属性取消了,理论上也不会出现这种问题了),就在NAT下客户端并发量比较大的情况下,出现连接不上的情况(应该是SYN后,没有收到SYNACK,连接被丢......
  • PDF标准详解(一)——PDF文档结构
    已经很久没有写博客记录自己学到的一些东西了。但是在过去一年的时间中自己确实又学到了一些东西。一直攒着没有系统化成一篇篇的文章,所以今年的博客打算也是以去年学到的一系列内容为主。通过之前Vim系列教程的启发,我发现还是写一些系列文章对自己的帮助最大。它能最大化自己的学......
  • 关于三次握手和四次挥手的详解
    我一看到TCP,啪就点进来了,很快啊。  TCP报文   一个完整的TCP报文头部共有20个字节,其中包括:源端口号(16位)和目的端口号(16位):再加上ip首部的源ip地址和目的IP地址可以唯一确定一个TCP连接。数据序号(16位):表示在这个报文段中的第一个数据字节序号。确认序号:仅当......
  • 详解Smooth_L1_Loss函数的计算方式
    详解SmoothL1Loss函数的计算方式在深度学习中,SmoothL1Loss函数是一种用于回归任务的损失函数。它在一定程度上克服了均方误差(MSE)损失函数的局限性,特别适用于处理离群值。简介SmoothL1Loss函数是HuberLoss的一种近似形式。它通过引入平滑因子,使损失函数在离群值附近呈现鲁棒......
  • 网络要素服务(WFS)详解
    通过实例详细介绍了WebGIS中网络要素服务(WFS)的具体内容。目录1.概述2.GetCapabilities3.DescribeFeatureType4.GetFeature4.1Get访问方式4.2Post访问方式5.Transaction5.1Insert5.2Replace5.3Update5.4Delete6注意事项1.概述WMS是一个返回图片......
  • 卷积神经网络详解+Python实现卷积神经网络Cifar10彩色图片分类
    原文链接:https://blog.csdn.net/master_hunter/article/details/133156758卷积神经网络相对于普通神经网络在于以下四个特点:局部感知域:CNN的神经元只与输入数据的一小部分区域相连接,这使得CNN对数据的局部结构具有强大的敏感性,可以自动学习到图像的特征。参数共享:在CNN中,同一个......
  • 2024最新苹果iOS17.3微信分身详解分享
    微信是目前最流行的社交软件之一,拥有庞大的用户群体。然而,对于一些需要同时使用多个微信账号的用户来说,使用官方版微信就显得有些不方便。iOS分身微信软件可以解决这个问题,它可以让用户在同一台设备上同时登录多个微信账号,从而实现工作生活两不误。iOS分身微信软件的优势iOS......
  • Windows 快速安装 tcping 工具
    首先,请确保你已经安装了Chocolatey。如果没有安装,可以在管理员权限的PowerShell窗口中运行以下命令进行安装:Set-ExecutionPolicyBypass-ScopeProcess-Force;[System.Net.ServicePointManager]::SecurityProtocol=[System.Net.ServicePointManager]::SecurityProtocol-bor......
  • MySQL 事务详解
    在数据库中,事务是一组操作单元,它们被视为一个独立的工作单元,要么完全执行,要么完全不执行。MySQL提供了强大的事务支持,允许开发者以一致的方式管理数据库操作。1.事务基础首先,我们需要了解事务的基础概念。一个事务通常包括以下几个关键特性:原子性(Atomicity):事务中的所有操作......