1. 简介
在计算机网络中,TIME_WAIT是TCP协议的一种状态,用于确保正确关闭连接并完全释放资源。在Linux系统中,TCP连接关闭之后,会进入TIME_WAIT状态一段时间。本文将从Linux源码的角度分析TIME_WAIT的持续时间。
2. TCP连接的关闭过程
TCP连接的关闭过程分为主动关闭和被动关闭两种情况。主动关闭是指连接的发起方主动关闭连接,被动关闭是指连接的接收方关闭连接。
2.1 主动关闭
在主动关闭过程中,主动关闭方发送一个FIN包给对方,表示自己没有数据要发送了,请求关闭连接。接收方在收到FIN包之后,发送一个ACK包确认收到FIN包,并继续在一段时间内接收数据。当接收方没有数据可发送时,也发送一个FIN包给主动关闭方,表示自己也要关闭连接。主动关闭方在收到FIN包之后,发送一个ACK包确认关闭连接,然后进入TIME_WAIT状态。
2.2 被动关闭
在被动关闭过程中,被动关闭方接收到对方发送的FIN包,并发送一个ACK包确认收到FIN包。然后继续接收数据,在一段时间内发送数据。当被动关闭方没有数据可发送时,发送一个FIN包给对方,表示自己也要关闭连接。对方在收到FIN包之后,发送一个ACK包确认关闭连接,然后进入TIME_WAIT状态。
3. TIME_WAIT的作用
TIME_WAIT状态的主要作用是确保连接的完全关闭,并保证之前连接的数据不会影响新的连接。在TIME_WAIT状态下,旧的连接信息会被保存一段时间,这样可以避免旧连接信息被新连接误用。
TIME_WAIT状态的持续时间通常是根据RFC规范建议的2倍MSL(Maximum Segment Lifetime)时间,MSL是指网络传输数据包的最大生存时间。在Linux系统中,默认的MSL时间是60s,所以TIME_WAIT状态的持续时间是120s。
4. Linux源码中TIME_WAIT的处理
在Linux内核源码中,TIME_WAIT状态的处理位于net/ipv4/tcp_timer.c文件中的tcp_time_wait()函数中。
4.1 tcp_time_wait()函数的功能
tcp_time_wait()函数的主要功能是处理TIME_WAIT状态下的定时器到期事件。该函数会在每个TCP连接关闭时启动一个定时器,定时器到期后会执行tcp_time_wait()函数,用于处理TIME_WAIT状态的相关操作。
4.2 TIME_WAIT状态的持续时间的计算
TIME_WAIT状态的持续时间是根据RFC规范建议的2倍MSL时间计算的。在tcp_time_wait()函数中,可以找到计算TIME_WAIT持续时间的相关代码:
#define TCP_TIME_WAIT_LEN (60*HZ) /* RFC 1337: TIME_WAIT is 2 minutes */
/* ... */
static void tcp_time_wait(struct sock *sk)
{
/* ... */
/* Calculate TIME_WAIT timer duration */
duration = tcp_fin_time(sk) + TCP_TIME_WAIT_LEN - tcp_time_stamp;
if (duration <= 0)
duration = TCP_TIME_WAIT_LEN;
/* ... */
}
可以看到,TCP_TIME_WAIT_LEN的值是60*HZ,HZ表示内核的时钟滴答频率,默认值是100。所以TCP_TIME_WAIT_LEN的实际值是60*100=6000ms,也就是6秒。
在计算duration变量时,首先获取到TCP连接关闭时的时间戳tcp_time_stamp,然后根据tcp_fin_time()函数计算FIN包传输时间,再加上TCP_TIME_WAIT_LEN,最后得到duration的值。如果duration小于等于0,则将其设置为TCP_TIME_WAIT_LEN的值。
4.3 清理TIME_WAIT状态
在tcp_time_wait()函数中,还会进行一些清理操作,以释放TIME_WAIT状态所占用的资源,例如移除定时器、从TCP连接队列中移除等。
5. 结论
通过分析Linux内核源码,我们可以得出以下结论:
TIME_WAIT状态的持续时间是根据RFC规范建议的2倍MSL时间,通常是120秒。
Linux内核将TIME_WAIT状态的处理逻辑放在tcp_time_wait()函数中。
TCP_TIME_WAIT_LEN的默认值是6秒,表示MSL时间的2倍。
对于用户来说,TIME_WAIT状态的持续时间可能会影响到系统的连接数和连接建立速度。因此,可以根据实际需求,调整内核参数来改变TIME_WAIT状态的持续时间。
总之,了解TIME_WAIT状态的作用和持续时间对于网络程序的性能优化和故障排查都非常重要。