TIME_WAIT状态

TIME_WAIT状态_第1张图片

客户端在接收到服务器的结束报文段之后,并没有直接进入closed状态,而是转移到了TIME_WAIT状态,在这个状态,客户端连接要等待一段长为2msl的时间(报文的最大生存时间),才能完全关闭,msl是tcp报文段在网络中的最大生存时间,标准文档的建议值是2min.

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

  • 可靠的终止tcp连接
  • 保证迟来的tcp报文段有足够的时间被识别并被丢弃

第一个原因很好理解。假设图中用于确认服务器结束的报文段的TCP报文段丢失,那末服务器将重发结束报文段。因此客户端需要停留在某个状态以处理重复收到的结束报文段(即向服务器发送结束报文段)。因此客户端要停留在某个状态以处理重复收到的结束报文段(即向服务器发送确认报文段),否则客户端将以复位报文段来回应服务器,服务器则认为是一个错误,因为他希望有一个向tcp报文段7那样的确认报文段。

在linux系统上,一个tcp端口不能被同时打开多次(两次及以上),当一个tcp连接处于TIME_WAIT状态时,我么将无法立即使用该连接占用着的端口来建立一个新连接,反过来思考,如果不存在TIME_WAIT状态,则应用程序能够立即建立一个和刚关闭的连接相似的连接(这里说的相似,是指他们具有相同的IP地址和端口号)。这个新的和原来相似的连接被称为原来的连接的化身,新的化身可能接收到属于原来的连接的,携带应用程序数据的TCP报文段(迟到的报文段),这显然是不能发生的,这就是TIME_WAIT状态存在的第二个意义。

另外,因为tcp报文段的最大生存时间为MSL,所以坚持2msl时间的TIME_WAIT状态能够确保网络上两个传输方向上尚未被接收到的,迟到的报文段都已经消失(被中转路由器丢弃)。因此,一个连接的 新的化身可以在2msl时间之后安全地建立,而绝对不会接收到属于原来连接的应用程序数据,这就是TIME_WAIT要持续2msl的原因。

有时候我们希望避免TIME_WAITZ状态,因为当程序退出后,我们希望立即重启这个程序,但是由于处于TIME_WAIT的程序还占用着这个端口,程序将无法启动(直到2MSL超时时间结束)

我们可以使用netstat命令查看连接的状态

如果服务器主动关闭连接后异常终止,因为它总是使用同一个知名服务端口号,所以连接的TIME_WAIT状态将导致它不能立即重启,不过我们可以通过socket 选项SO_REUSEADDR来强制进程立即使用TIME_WAIT状态的连接占用的端口

你可能感兴趣的:(Linux)