TCP三次握手/四次挥手-常见问题(不断更新中)

三次握手,记在了网络是怎样连接的P65-66.此处不再赘述。
四次挥手:
TCP三次握手/四次挥手-常见问题(不断更新中)
这图中着重提到了MSL。那啥是MSL啊?MSL是指Max segment Lifetime,即数据包在网络中的最大生存时间。每种TCP协议的实现方法均要指定一个合适的MSL值,如RFC1122给出的建议值为2分钟,又如Berkeley体系的TCP实现通常选择30秒作为MSL值。这意味着TIME_WAIT的典型持续时间为1-4分钟。

说人话:在Linux系统中,2MSL时长为1min, 在Windows系统中,2MSL时长为4min.

我们再贴一个翻译版的图:
TCP三次握手/四次挥手-常见问题(不断更新中)
那么,提出MSL的概念,是用来做什么呢?换句话说,MSL的提出用于解决哪些问题呢?见名知意。MSL是数据包在网络中的最大生存时间。也就是说,数据包在网络中的寿命就是MSL。超过MSL就可以保证这个数据包绝对死在网络世界中了。

MSL的意义

(1)可靠地实现TCP全双工连接的终止

为了保证A发送的最后一个ACK报文段能够到达B。
A给B发送的ACK可能会丢失,B收不到A发送的确认,B会超时重传FIN+ACK报文段,此时A处于2MSL时间内,就可以收到B重传的FIN+ACK报文段,接着A重传一次确认,重启2MSL计时器。最后,A和B都能够正常进入到CLOSED状态。

如果A在发完ACK后直接立即释放连接,而不等待一段时间,如果这个ACK丢掉了,就无法收到B重传的FIN+ACK报文段,也就不会再次发送确认报文段,这样,B就无法按照正常步骤进入CLOSED状态。

(2)允许旧的报文段在网络中消逝

A发送确认后,该确认报文段可能因为路由器异常在网络中发生“迷途”,并没有到达B,该确认报文段可以称为旧的报文段。A在超时后进行重传, 发送新的报文段,B在收到新的报文段后进入CLOSED状态。在这之后,发生迷途的旧报文段可能到达了B,通常情况下,该报文段会被丢弃,不会造成任何的影响。但是如果两个相同主机A和B之间又建立了一个具有相同端口号的新连接,那么旧的报文段可能会被看成是新连接的报文段,如果旧的报文段中数据的任何***恰恰在新连接的当前接收窗口中,数据就会被重新接收,对连接造成破坏。为了避免这种情况,TCP不允许处于TIME_WAIT状态的连接启动一个新的连接,因为TIME_WAIT状态持续2MSL,就可以保证当再次成功建立一个TCP连接的时,来自之前连接的旧的报文段已经在网络中消逝,不会再出现在新的连接中。

那么,为什么是2MSL呢?

在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。