专业的编程技术博客社区

网站首页 > 博客文章 正文

TCP漫谈之为啥需要timewait状态

baijin 2024-12-03 10:03:33 博客文章 7 ℃ 0 评论

TCP的状态转化如下图所示,其中time_awit状态是CLOSED之前的一个状态,等待2个MSL时间。

为什么需要time_awit状态呢?为什么不直接进入closed状态呢?直接进入closed状态不就能更快地释放资源给新的连接使用了吗?而是需要2MSL(linux默认)的等待时间呢?

有两个原因,第一个原因是为了防止出现“迷路的数据包”,如下图所示,如果在第一个连接里面第三个数据包由于底层网络故障延迟送达,新的连接建立后,这个迟到的数据包才到达,那么将会导致接收数据紊乱。

第二个原因则更加简单,如果因为最后一个ack丢失,那么对方将一直处于last ack状态,如果此时重新发起新的连接,对方将返回RST包拒绝请求,将会导致无法建立新连接。

为此,设计了time_awit状态。在高并发情况下,如果能将time_awit的tcp复用,那么便可以极大地提高并发效率。Time_awit的tcp复用是指可以将处于time_awit状态的连接重复利用起来,从time_awit转化为established,继续使用。linux内核通过net.ipv4.tcp_tw_reuse参数控制是否开启time_awit状态复用。那么读者可能很好奇,之前不是说time_awit设计之初是为了解决上面两个问题的吗?如果直接复用不是会导致上面两个问题吗?这里先介绍linux默认开启的一个tcp时间戳策略net.ipv4.tcp_timestamps = 1,时间戳开启后,针对第一个迷路数据包的问题,由于晚到数据包的时间戳过早,这个数据包会被直接丢弃,不会导致新连接的数据包紊乱。针对第二个问题,当开启reuse后,当对方处于last-ack状态时,发送syn包会返回FIN,ACK包,然后客户端发送RST让服务端关闭请求,从而客户端便可以再次发送syn建立新的连接了。

最后还需要提醒读者的是,linux 4.1内核版本之前除了tcp_tw_reuse以外,还有一个参数tcp_tw_recycle,这个参数就是强制回收time_wait状态的连接,它会导致NAT环境丢包,所以不建议开启。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表