tcp的三次握手与四次挥手-------屌丝与女神的恋爱记
前言
记得以前学习tcp的三次握手跟4次挥手的时候,就一直有疑惑,今天就又看了一遍书上的内容,结果突然一下豁然开朗,阳关明媚,碧海蓝天,哈哈。在这里想安利一波,学习计算机网络必读经典—-《计算机网络》–谢希仁编著。目前已经出版到第7版。最好多读几遍,绝对获益匪浅。-
申明
好了,我们进入今天的正题—tcp的三次握手与四次挥手。在这里我先做一下约定:
我:客户端
女神:服务器刚开始是我和女神都没连接,两端的tcp进程都处于关闭状态。在这里我主动给女神发消息,约她去看电影。
-
tcp的三次握手建立连接
(第一次握手)我:你好,今天晚上可以一起去看电影吗,
(向服务器主动发起连接)(第二次握手)女神:嗯,收到了你的消息,在电影院等你,
(服务器收到了客户端的连接报文,同意连接,就向客户端发送确认,告诉客户端,服务器这边已经收到了连接请求)(第三次握手)我:嗯,没问题,不见不散。
(客户端收到服务器的确认后,向服务器发送确认,告诉服务器,客户端这边确实收到了你那边发来的确认)
好了,到这里,tcp的三次握手已经建立啦,现在我可以和女神正常聊天啦,,,,
- 问题:为什么我在最后还要发送一次确认呢???
答:为了防止已经失效了的连接请求报文突然又传送到了服务器端,因而产生错误。
那么什么是已经失效的连接请求报文呢,
我们知道,客户端发出去的连接请求会出现三种情况:
1.正常情况下,数据流畅到达;
2.第一次连接请求报文丢失,未收到确认。于是重传,收到确认,连接建立;
3.出现一种异常情况,客户端发出去的连接请求报文没有丢失,而是在某些网络节点长时间滞留了,以致延误到连接释放以后的某个时间才到达。本来这是一个早已经失效的报文段,,但是服务器此失效的连接请求报文断后,就误以为是客户端又发出一次新的连接请求,于是发出确认,同意连接。这时候女神收到了这条失效的连接请求,于是就在某个地方等我,由于我现在并没有发出连接请求,就不知道女神在等我,于是女神就等了我好久也没等到。所以第二天女神就不理我啦,,,,,(哭,,,,,)。
这就是两次握手的缺点,会造成服务器资源的浪费。
-
tcp的四次挥手释放连接
先上一张原理图
tcp的四次挥手释放连接其实没有那么难,这里我用很通俗的语言来说明。
接下来,就是我与女神的故事第二弹了。这时候,我已经与女神看完电影从电影院出来了,我们相处的很开心,这时候已经不早了,我打算跟女神道别了,于是, - (第一次挥手)我:已经不早了,我们回去吧,
(客户端向服务器发送连接释放报文段,并停止再发送数据,主动关闭tcp连接,这是客户端进入FIN-WAIT1状态) - (第二次挥手)女神:什么,这就要回去了?
(服务器向客户端发出确认,告诉客户端已经收到了连接释放报文段,这时候服务器进入CLOSED-WAIT状态)
这时tcp连接处于半关闭状态,这是什么意思呢?就是在说,我觉得已经不早了,该回去了,于是询问女神,结果女神玩的很开心,现在还不想回去。即客户端没有数据要发送了,但服务器若发送数据,客户端仍要接受。也就是说,从服务器到客户端的连接并没有关闭,这个状态可能会持续一段时间。
我收到了女神的确认,好吧,女神还不想回去呢,没办法啊,只能等待女神的下一步指示喽,,,,,客户端进入FIN-WAIT2状态,等待服务器发出的连接释放报文段。 (第三次挥手)女神:好吧,今天先饶过你,明天记得来接我。
(这时候服务器进程就通知tcp释放连接,于是发出连接释放报文段,这时服务器进入LAST-ACK状态,等待客户端的确认消息)(第四次挥手)我:嗯,知道了,那我送你回家吧。
(客户端收到服务器端的连接释放报文段之后,必须发出确认,告诉服务器确实收到了你那边的连接释放报文,注意:这时候连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,客户端才进入CLOSED状态)
MSL(maximum Segment Lifetime):最长报文段寿命
问题:为什么客户端在TIME-WAIT状态必须等待2MSL的时间呢?
答:原因有两点:
- 为了保证客户端发出的最后一个ACK报文段能够到达服务器。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的服务器收不到客户端已经发送的FIN和ACK报文段的确认,连接无法正常关闭。
- 为了防止上面提到过的“已失效的连接请求报文段”出现在本链接中。客户端在发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本链接次持续的时间内所产生的所有版文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。