TCP的三次握手
通信所要解决的首要问题就是,保持通信双方的信息对称,使通信双方处于同步状态。
先来一个例子:
罗密欧大学期间写信给中学同学朱丽叶,信的内容如下:
小叶子,我喜欢你!
这封信发出之后,罗密欧无法知道朱丽叶能否收到,只有收到小叶子的回信,才能知道自己的信已经到达对方。
三天之后,小叶子回信了,信的内容如下:
小欧,来信已阅,我也喜欢你…
此时,小叶子眼中双方的状态是:互相爱慕!
如果小欧收到回信,小欧眼中双方的状态也是:互相爱慕!
如果小欧没有收到回信,小欧眼中双方的状态是:单相思!
小叶子为了杜绝小欧模棱两可的状态,使他与自己达成“互相爱慕”的共识,需要做以下工作:
1)先耐心地等小欧的第三封信
2)如果若干天没有收到回信,需要把自己的第二封信再次发出
如果收到了小欧的回信,那么双方的状态终于同步了:“互相爱慕”!
即使2)发生了,N天之后也可以达成同步状态。
之后,双方可以甜言蜜语地谈恋爱了。
TCP四次挥手
主动断开的一侧为A,被动断开的一侧为B。
第一个消息:A发FIN
第二个消息:B回复ACK
第三个消息:B发出FIN
此时此刻:B单方面认为自己与A达成了共识,即双方都同意关闭连接。
此时,B能释放这个TCP连接占用的内存资源吗?不能,B一定要确保A收到自己的ACK、FIN。
所以B需要静静地等待A的第四个消息的到来:
第四个消息:A发出ACK,用于确认收到B的FIN
当B接收到此消息,即认为双方达成了同步:双方都知道连接可以释放了,此时B可以安全地释放此TCP连接所占用的内存资源、端口号。
所以被动关闭的B无需任何wait time,直接释放资源。
但,A并不知道B是否接到自己的ACK,A是这么想的:
1)如果B没有收到自己的ACK,会超时重传FiN
那么A再次接到重传的FIN,会再次发送ACK
2)如果B收到自己的ACK,也不会再发任何消息,包括ACK
无论是1还是2,A都需要等待,要取这两种情况等待时间的最大值,以应对最坏的情况发生,这个最坏情况是:
去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL)。
这恰恰就是2MSL( Maximum Segment Life)。
等待2MSL时间,A就可以放心地释放TCP占用的资源、端口号,此时可以使用该端口号连接任何服务器。
为何一定要等2MSL?
如果不等,释放的端口可能会重连刚断开的服务器端口,这样依然存活在网络里的老的TCP报文可能与新TCP连接报文冲突,造成数据冲突,为避免此种情况,需要耐心等待网络老的TCP连接的活跃报文全部死翘翘,2MSL时间可以满足这个需求(尽管非常保守)!
原文地址 作者:车小胖 链接:https://www.zhihu.com/question/67013338/answer/248375813