回答此问题的关键就是“延迟”,脱离了这个关键便很容易陷入牵强附会式的理解中。

很多人都意图用通俗的比喻来阐述“三次握手”的原理,虽然形式各异,但普遍都是用人与人之间的“对话”来类比。但这里要给出一个结论:只要使用“对话”这种形式来类比“三次握手”的,基本都是牵强附会。

本文借用《鸟哥的Linux私房菜》作者鸟哥对“三次握手”的比喻举例。鸟哥是我非常尊敬的技术前辈,也是买了他的书才知道他也是用类似的比喻来教学生“三次握手”的。

在鸟哥的比喻中,第一次握手是鸟哥说:A同学你在不在?第二次握手则是A同学回答:我在!那鸟哥你在不在?第三次握手则是鸟哥回答:我也在。

鸟哥这个情景比喻其实是有些牵强附会的,为啥呢?因为它本身就存在逻辑漏洞,现实中不会有人用那种方式沟通,如果有也多半会被当成脑子有问题。

这个逻辑漏洞就在第二次握手时A同学的回答中,他说“我在!那鸟哥你在不在?”。

这句话分为两部分,A同学先回答说“我在!”,说明他有先听到鸟哥的问话,既然听到了那肯定就已经知道鸟哥在了,后面又多此一举问“那鸟哥你在不在?”显然就是在牵强附会故意往“三次握手”上靠。

也许有人会替鸟哥解释,第一次握手时鸟哥只是说“A同学你在不在”,并没有介绍自己的身份,所以A同学的第二次握手才重复确认。可是,如果第二次握手时A同学真的不知道第一次握手来自鸟哥,他怎么会问“鸟哥”在不在,而不是问别人?

拿一个现实中不存在的杜撰场景来解释一个抽象的概念,显然是缺乏说服力的。现实中的对话,包括电话通信,其实都是采用的“两次握手”机制。

比如打电话时,发起方问“我是谁谁,请问你是谁谁吗?”,接收方回答“我是,请讲”。或者面对面沟通,发起方说“可以聊聊吗?”,接收方回答“可以,请坐”。这才是正常的沟通方式,都是“两次握手”足以。

为啥它们不需要“第三次握手”呢?

因为在这些“对话”场景中,基本都是可以忽略“延迟”之存在的。无论是面对面的声波传递,还是非面对面的电波,在连接的主体“人”看来,其消息延迟基本都是零。而三次握手要面临的通信场景中,延迟则是不可忽略的重要因素。

在真实的计算机网络中,电信号或者光信号固然仍旧非常快,但是考虑到远距离信号传输介质的相对廉价性,以及实际因距离产生的时延,导致信号的传输速度对于网络中主机的信息处理速度而言就显得非常慢,这时延迟就成了一个无法回避的问题。

这里不禁想到曾风靡一时的末日僵尸片中的经典桥段,即主角团一行人忽然听到广播,说在某某地方有生活物资充沛的避难所,可是经过千辛万苦到达避难所后却发现那广播只是一个“迟到的消息”,避难所早已被僵尸摧毁了。

这其中就暗喻了在无法忽视“延迟”的通信场景中,第三次握手的重要性。

在那个电影桥段中,来自“避难所”的广播可以视为第一次握手。但信息的接收方主角团其实无法确认这个广播的真实性,以及有效性。这时最合理的对策就是找一个电台进行“第二次握手”的反向广播,确认消息的有效性,且在没有收到对方“第三次握手”的应答广播之前不贸然前往。

在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。其中“失效的连接请求”就可以视为前面电影桥段中那个来自“庇护所”的广播,产生的错误则是主角团的贸然前往。

在另一部经典的《计算机网络》一书中讲“三次握手”的目的是为了解决“网络中存在延迟的重复分组”的问题。这本书则更明确地指向了问题的关键“延迟”,也就是本文开头所强调的。

总结就是,在建立TCP连接时,连接的接受方必须依靠那不可省略的、来自连接发起方的“第三次握手”来确认当前连接请求的有效性,而让连接有效性成为问题的根本原因则是“延迟”。

-END-

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。