ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
上一篇文章提到执行主动关闭的一端进入 tcp TIME_WAIT状态,关于原因,unix网络编程卷一中给出两点: 1. 实现终止TCP全双工链接的可靠性,即保证tcp连接可靠断开。 2. 让老的重复分节在网络中消失 第一个原因的解释,执行主动关闭的一端最终会发ACK给对端,如果这个ACK最终丢失,那么发FIN的对端将由于在等待ACK超时后重发FIN分节,而如果主动关闭的一端在发完最终的ACK后清除此连接上状态信息,当再次收到对端的FIN分节时由于找不到对应的连接而报错,所以,如果TCP想彻底终止某个连接上两个方向的数据流(即全双工关闭),那么它必须处理连接终止序列四个分节中任何一个分节丢失的情况,这就是为何执行主动关闭的一端进入TIME_WAIT状态的第一个原因,因为它可能不得不重发最终的ACK分节给对端。 第二个原因,假设在一对ip及port上有一个连接,关闭这个连接后立即又建立起新的连接(同ip port),后一个连接为前一个的化身,因为ip port相同,tcp 必须防止来自某个连接的老分组在连接终止后再现,从而影响新连接的数据交互,所以tcp不能给处于TIME_WAIT状态的连接启动新的化身,从而被误解成属于同一连接。 TIME_WAIT状态的持续时间是最长分节生命期MSL(max segment lifetime)的2倍,即2MSL,既然tcp规定一个分节在网络中最大生存时间是 MSL,这足够让某个方向上的分节最多存活MSL秒即被丢弃,另一个方向的应答最多存活MSL秒也被丢弃,通过这个规则,就能保证当成功建立一个tcp连接时,来自该链接的之前所有连接的老的重复分组在网络中已消失。 每个TCP/IP 协议栈必须选择一个 MSL值,rfc 1122建议值为2分钟,而源自berkely的实现是30秒,需要注意的是如果此值过大,则在高并发服务器中tcp/ip协议栈必然要维护大量的TIME_WAIT状态的连接而消耗资源,所以一般作网络服务器优化时通常经过改小此值来减少维护此状态的资源。 详细设置及解决如下: timeout_timewait 参数 描述:确定 TCP/IP 在释放已关闭的连接并再次使用其资源前必须经过的时间。关闭与释放之间的这段时间称为 TIME_WAIT 状态或者两倍最大段生存期(2MSL)状态。此时间期间,重新打开到客户机和服务器的连接的成本少于建立新连接。通过减少此条目的值,TCP/IP 可以更快地释放关闭的连接,并为新连接提供更多资源。如果正在运行的应用程序需要快速释放连接、创建新的连接,并且因为许多连接处于 TIME_WAIT 状态而导致低吞吐量,那么调整此参数。 如何查看或设置: 在我的ubuntu系统上此值为: #cat  /proc/sys/net/ipv4/tcp_fin_timeout  60 发出以下命令,将 timeout_timewait 参数设置为 30 秒: #echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout