这是一个网上充分讨论过且面试里经常被问到的一个看似非常基础的问题,网络上也已经有无数的帖子讨论过了,看过不少,都是很专业且详细的,在此我尝试着用比喻的方法和角度进行比较形象的解读。
想象下生活中寄快递的场景,卖家在寄出包裹给买家时,除了知晓买家的收货地址外,对买家的信息,如地址是否正确,收货人是否有空接收包裹,是无法确保的。但他不管,先寄过去再说,大不了退回,这就像极了UDP协议,当然UPD是不会退回消息而是直接丢弃的。现在言归正传说下TCP,如果说UDP像寄包裹,TCP则像极了古代两个遥远的国度建立正式的外交关系。
古时,有个叫“Client国”的想与遥远的“Server国”建立外交关系,但是由于路途遥远通讯不便,“Client国”并不知道“Server国”是否存活着(毕竟那个年代,战争连绵,国被灭是常有的事),同理,“Server国”不知道“Client国”是否活着。于是,“Client国”主动派出了使臣:
第一次:Client国使臣: Hello, Server国,我活着,建交不?
第二次:Server国使臣:Hello, Client国,我也活着,好啊!建交吧!
第三次:Client国使臣:好啊!
于是乎,双方如火如荼开始盖使馆了(可比喻分配相应内存建立连接资源)......
这里,有个有趣的问题的,有了前两次的沟通不就可以建交了么,为何还要劳烦Client国使臣大老远再跑一趟呢?这里我们需要理解下两国互派使臣的目的是啥?其实就俩目的:1. 知道对方活着。2. 告诉对方,俺知道你活着(或者换个方式说,知道对方知道自己活着)。那为啥要有第二个目的呢?你想啊,我知道你活着,但万一你以为我不知道呢?我得通知你啊,这样你才肯建使馆嘛,毕竟建交事大,得谨慎不是!同理,对方也是这么想的。因此:
-
通过第一次握手,Server国知道Client国活着。
-
通过第二次握手,Client国知道Server国活着。同时,Server国告诉Client国:我收到你信息了,我知道你小子还活着哪!(或者说,通过第二次握手,Client国知道了Server知道自己活着)。巴特 However, Server国就想啊:Client国这小子知不知道我活着呢?于是......
-
通过第三次握手,Client国也告诉Server国:嘿!小子!俺知道你也活着哪!开始吧....
至此,双方都知道对方活着也告诉对方我知道你活着(或者说:知道对方知道自己活着),成功建交。细心者可以发现到第二步完,Client国已经可以盖使馆(建立连接资源),而Server国要等到第三步完。
看完握手,我们再来理解下挥手。同样场景,还是Client和Server这两国,经过一段时间的通商交流(数据传输),双方都觉得完成历史使命,开始相看两厌,准备断交了。于是,
第一次:Client国使臣:Server国,老子不陪你玩了,你的使馆我打算拆了搞房地产,就知会你下!
第二次:Server国使臣:好吧!我认!
经此两步,Client国真的把Server国使馆拆了(释放链接资源),从此由于Client国到Server国的通道已被切断,再无人员可从Client国到Server国了;但是,从Server国到Client国的通道却仍然还在,人员仍然可从Server国去往Client国,只是已经少之又少了。Server国想想觉得窝囊,于是:
第三次:Server国使臣:Client国,你不仁在先,老子也不陪你玩了,分手吧!
第四次:Client国使臣:好吧!再见!
经过这两步,Server国也把Client国使馆拆了(释放链接资源),断了通路。至此,两国正式断交。
这里的第二步和第三步理论上可以同时做掉,但实际通常不这么做的原因在于:虽然Client通往Server的路断了,但Server通往Client的路却有可能仍有短暂保留的必要,可以理解为作为被动的Server一方措手不及,需要点小小时间处理下遗留问题,但马上立刻迅速就跟你断!

而且了,断交这事,并不一定总是有Client国主动挑起,有可能双方同时发现对方已无价值,同时发出断交声明,于是就如下图:

总之呢,这只是对3次握手和4次挥手的一个形象化的解读,目的是为了更好理解和记忆,当然实际的情况会是更复杂些的。一家之言,仅供参考。