TIME_WAIT状态
TIME_WAIT状态
执行主动关闭的一方处于TIME_WAIT状态。端点留在这个状态的时间是2MSL(最长分节生命期: maximum segment lifetime)。
任何TCP实现都必须为MSL选择一个值, RFC1122建议值2分钟,BSD的实现30秒。所以,MSL在1——4分钟之间。MSL是任何IP数据报能够在因特网中存活的最长时间。这个时间是有限制的,每个数据报都有一个跳限(hop limit)的8位字段,最大值255。具有最大255跳限的分组在网络中存在的最长时间不超过MSL。
TIME_WAIT存在的两个理由:
(1)可靠地实现TCP全双工连接的终止。
这个可以由主动关闭的客户端最终的ACK丢失解释。服务器未收到ACK,它将重新发送最终的FIN,因此客户必须状态信息。若客户端直接终止,对于收到的FIN会响应一个RST分节,该分节被服务器解释为错误。
若TCP打算执行所有必要的工作以彻底终止某个连接上两个方向上的数据流(全双工关闭),则它必须正确处理连接终止序列4个分节任何一个丢失的情况。
主动关闭的端处于TIME_WAIT: 因为可能不得不重传丢失的最终哪个ACK。
(2) 允许老的重复分节在网络中消逝。
TCP不允许处于TIME_WAIT状态的端点建立新的连接。目的防止老的重复分组不会发送到新建立的连接目的端,由于TIME_WAIT会处于2MSL时间,保证了某个方向的分组最多存活MSL(数据+ACK=2MSL,一个方向上最多2MSL)即被丢弃。
注意: 一个例外: 如果到达的SYN的序列号 > 前一个化身(连接)的结束序列号, BSD的实现允许给当前处于TIME_WAIT状态的连接启用新的化身。
1. 避免TIME_WAIT状态
可以使用SO_LINGER套接字选项关闭TIME_WAIT状态,但是一般不这么做。
struct linger {
int l_onoff; /* 0=off, nonzero=on */
int l_linger; /* linger time, POSIX specifies units as seconds */
};
l_onoff != 0; l_linger = 0; 避免TIME_WAIT状态。
例子:
struct linger ling = {1, 0};
setsockopt(SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger));
2. 通过系统配置文件修改TIME_WAIT状态
通过修改/etc/sysctl.conf中相关参数,进行适当调整。