您的位置:首页 > 理论基础 > 计算机网络

TCP连接终止前的TIME_WAIT状态

2016-03-25 18:48 627 查看

TIME_WAIT状态

客户端连接在接收到服务器结束报文段之后,并未直接进入CLOSED状态,而是转移到TIME_WAIT状态。

在这个状态,客户端连接要等待一段长为
2 MSL
(Maximum Segment Life,报文段最大生存时间)的时间,才能完全关闭。

MSL是TCP报文段在网络中最大生存时间,标准文档RFC 1122的建议值是2min(即2分钟)。

为何会有TIME_WAIT?

TIME_WAIT状态存在的原因有两点:

1、可靠地终止TCP连接。

2、保证让迟来的TCP报文段有足够的时间被识别并丢弃。

为何要这么做?

1的原因:

如果客户端给服务端发的最后一个ACK确认结束的报文丢失,那么服务器将重发结束报文段。

因此客户端需要停留在某个状态以处理重复收到的结束报文段。

不然客户端将回应服务器一个复位报文段(RST),服务器则会认为此是一个错误,因为它在等待客户端确认关闭连接的最后一个确认报文段(ACK)。

2的原因:

Linux系统上,一个TCP端口不能被同时打开多次。

当一个TCP连接处于TIME_WAIT状态时,将无法立即使用该连接占用着的端口来建立一个新连接。

如果没有TIME_WAIT状态,应用程序能够立即建立起一个和刚关闭的连接相似的连接。

这个新的、和原来相似的连接被称为原来连接的化身。新的化身可能接收到属于原来的连接的某些TCP报文段,显然不应该发生这种情况。

为啥是2MSL?

因为MSL是TCP报文段在网络中最大生存时间,所以2MSL的时间能保证网络上两个传输方向上尚未接收到的、迟到的TCP报文都已经丢失。

因此一个连接的新的化身可在2MSL之后安全地建立,而不会收到属于原来的连接的应用程序数据。

避免TIME_WAIT状态

避免目的:希望程序退出后能够立即重启。

由于客户端端口号的随机性,客户端一般和程序上次使用的端口号(TIME_WAIT状态)不同,所以客户端一般可以立即重启。

但是服务端总是使用同一个知名服务端口号,所以连接的TIME_WAIT状态将导致它不能立即重启。不过,我们可以通过socket选项

SO_REUSEADDR
来强制进程立即使用处于TIME_WAIT状态的连接占用端口。

知识来源:《Linux高性能服务器编程》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: