0


TCP 协议的 time_wait 超时时间

优质博文:IT-BLOG-CN

灵感来源在这里插入图片描述

Time_Wait 产生的时机

TCP

四次挥手的流程
在这里插入图片描述
如上所知:客户端在收到服务端**第三次

FIN

挥手**后,就会进入

TIME_WAIT

状态,开启时长为

2MSL

的定时器。
【1】

MSL

Maximum Segment Lifetime

报文最大生存时间,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为

TCP

报文是基于

IP

协议的,而

IP

头中有一个

TTL

字段,是

IP

数据报可以经过的最大路由数,每经过一个处理他的路由器值就会减

1

,当此值为

0

则数据报将会被丢弃,同时发送

ICMP

通知源主机;

**

MSL

TTL

的区别:**

MSL

单位是时间,

TTL

是经过路由跳数。所以

MSL

应该大于等于

TTL

消耗为

0

的时间,以确保报文已被自然消亡。

【2】

2MSL

的时间是从客户端接收到第三次握手的

FIN

后发送

ACK

开始计时的;

如果在

TIME-WAIT

时间内,因为客户端的

ACK

没有传输到服务端,客户端又收到了服务端重发的

FIN

报文,那么

2MSL

时间将重新计时。

【3】

Linux

系统停留在

TIME_WAIT

的时间为固定的

30

秒。这个数值是硬编码在内核中的,也就是说除非你重新编译内核,否则没法修改它;

#defineTCP_TIMEWAIT_LEN(60*HZ)
TTL

的值一般为

64

MSL

一般为

30s

,意味着

Linux

数据报文经过

64

个路由器时间不会超过

30s

,如果超过了则认为报文已经消息在网络中。

【4】客户端在收到服务端重传的

FIN

报文时,

TIME_WAIT

状态的等待时间会重置回

2MSL

2MSL

解释:网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又向对方发送响应,所以一来一回就是

2

MSL

时间。

如果被动关闭方

Server

没有收到断开连接的

ACK

报文,就会触发超时重发

FIN

报文,另一方

Client

接收到

FIN

后,会重发

ACK

给被动关闭方,一来一回正好

2

MSL

主动发起关闭连接的一方才会有

TIME-WAIT

状态。

为什么需要 TIME- WAIT状态

【1】确保被动关闭方已经关闭了连接: 当主动关闭方发出最后的

ACK

后,如果由于某种异常导致报文丢失,被动方没有收到最后的

ACK

报文会一直处于

LAST-ACK

状态,无法进入

CLOSED

状态。

假设主动关闭方跳过

TIME_WAIT

状态或者处于

TIME_WAIT

状态很短的时间后进入

CLOSED

状态,此时主动关闭方如果使用相同的源端口,发起

SYN

连接请求,被动关闭方由于还处于

LAST_ACK

状态,收到

SYN

包,此时就会回复

RST

包,导致新连接无法正常建立起来。
在这里插入图片描述
**【2】新的

TCP

连接被建立起来了,延迟包可能干扰新的连接:** 当使用原来的五元组来建立新的

TCP

连接,如果上一次连接还有数据报文,由于网络拥塞等原因,在新连接建立后才到达(且序列号一致),此时就会干扰到新的连接了,当然出现这种问题的概率比较低。
在这里插入图片描述

TIME_WAIT 资源使用情况

【1】查询方式: 通常在业务中可以使用

netstat

命令来查看系统的网络连接状态:

// 查看当前所有连接的状态,包括 TIME_WAIT 状态
netstat -an

// 查看指定 IP 地址和端口的连接状态
netstat -an | grep [IP]:[port]// 查看所有状态为 TIME_WAIT 的连接
netstat -an | grep TIME_WAIT// 查看所有 TIME_WAIT 状态的连接并统计数量
netstat -an | grep TIME_WAIT| wc -l

TCP

协议中,客户端通常会使用一个随机的端口号来与服务器建立连接。每一个

TIME_WAIT

状态,都会占用一个「本地端口」,上限为

65535

。本地端会等待两倍的

MSL

Maximum Segment Lifetime

,最大报文生存时间)的时间,这个时间通常为几分钟,之后才会释放该端口。如果这个时候新连接使用了这个端口,就可能出现数据混乱或者安全问题。

**【2】

TIME_WAIT

占用系统资源:** 整个系统建立连接时占用的资源:
☑️ **建立

TCP

连接**时,客户端需要指定目标服务器的

IP

地址和端口号,这个过程可能需要进行

DNS

查询和端口扫描等操作,这些操作可能会消耗一些资源
☑️ **短时间内频繁建立和关闭

TCP

连接** ,

TIME_WAIT

状态连接会占用系统的端口号和内存等资源,从而影响系统的性能
☑️ 随机端口号范围小了,引发端口号竞争, 临时端口号的竞争可能会导致

TCP

连接建立失败或者连接超时

**【3】

TIME_WAIT

与连接池的关系:** 使用连接池可以有效地减少连接的创建和关闭次数,从而减少

TIME_WAIT

状态下的连接数量。同时,连接池还可以通过控制连接数量、超时时间等参数,进一步优化连接的使用效率。

但是,如果连接池中存在大量的

TIME_WAIT

状态下的连接,那么连接池的效率可能会受到影响,从而导致系统性能下降。因此,需要通过调整连接池的参数,如最大连接数量、连接超时时间等,来避免

TIME_WAIT

问题的影响。

**【4】

TIME_WAIT

TCP_SYNC

**

**

TCP_SYNC

:** 攻击者利用伪造的

SYN

报文不断向受害者的服务器发送连接请求,但是连接并不能完成三次握手,最终服务器会不断创建半连接,引发系统崩溃。

攻击中,攻击者会大量发送伪造的

SYN

报文,但不回应服务器的

SYN+ACK

报文,从而使服务器不断等待客户端的

ACK

报文,最终导致服务器的连接队列被占满,无法响应正常连接请求。

TIME_WAIT

TCP_SYNC

本身没有联系,只是半连接在一定时间后会变成

TIME_WAIT

状态,就可以观测到

TIME_WAIT

数量增多。

**

TIME-WAIT

状态的危害:**
【1】占用系统资源: 如果服务端主动发起关闭连接方的

TIME-WAIT

状态过多。比如文件描述符、内存资源、

CPU

资源、线程资源等;
【2】端口资源: 如果客户端主动发起关闭连接方的

TIME-WAIT

状态过多。端口资源有限,一般可以开启的端口为

32768~61000

,也可以通过

net.ipv4.ip.local_port_range

参数指定范围。只要连接的是不同的服务器,端口还是可以重复使用的;

TIME-WAIT 优化

【1】

net.ipv4.tcp_tw_reuse

tcp_timestamps

net.ipv4.tcp_tw_reuse = 1

表示开启重用,允许将

TIME-WAIT socket

重新用于新的

TCP

连接。默认为

0

,表示关闭。

net.ipv4.tcp_tw_reuse =1
Linux

内核参数开启后,则可以复用处于

TIME_WAIT

socket

为新的连接所用。

.tcp_tw_reuse

功能只能为客户端为发起方,因为开启该功能,在调用

connect()

函数时,内核会随机找一个

time_wait

状态超过

1s

的连接给新的连接复用。

使用该选项的前提需要打开对

TCP

时间戳的支持,即:默认为

1
net.ipv4.tcp.timestamps=1

这个时间戳的字段是在

TCP

头部的选项里,它由一共

8

个字节表示时间戳,其中第一个

4

字节字段用来保存发送该数据包的时间,第二个

4

字节字段用来保存最近一次接收对方发送到达数据的时间。

由于引入了时间戳,前面提到的

2MSL

问题就不存在了,因为重复的数据包会因为时间戳过期被自然丢弃。

【2】

net.ipv4.tcp_max_tw_buckets

设置上限值,默认值为

18000

,当系统中处于

TIME_WAIT

的连接一旦超过这个值时,系统就会将后端的

TIME_WAIT

连接状态重置,比较暴力。
【3】

TCP

协议栈有个

keepalive

的属性,可以主动探测

socket

是否可用,不过这个属性的默认值很大。
全局设置可更改

/etc/sysctl.conf

,加上:

net.ipv4.tcp_keepalive_intvl =20 net.ipv4.tcp_keepalive_probes =3 net.ipv4.tcp_keepalive_time =60

在程序中设置如下:

int keepAlive =1;// 开启keepalive属性 int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测 int keepInterval =5;// 探测时发包的时间间隔为5 秒int keepCount =3;// 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.

本文转载自: https://blog.csdn.net/zhengzhaoyang122/article/details/140242809
版权归原作者 程序猿进阶 所有, 如有侵权,请联系我们删除。

“TCP 协议的 time_wait 超时时间”的评论:

还没有评论