关于如何理解TCP的三次握手与四次挥手

简介

TCP协议中的的三次挥手和四次挥手简单来说就是TCP连接建立的过程和断开的过程,

三次握手

第一次握手即client端发送一个带有SYN标志位的同步TCP报文段向server端,表示请求连接。同时,该报文段包含一个序号。
第二次握手即server端发送一个TCP报文到client端表示确认连接,这个TCP报文也带有SYN标志位,同时发送自己的序号,并对第一个报文中的序号加一表示确认收到。
第三次握手即client端对server端发来的第二个TCP报文段的确认,client端会把第二个TCP报文段序号值加一发送给server端。
这个过程就称为建立TCP连接的三次握手。

四次挥手

第一次挥手即第一个TCP报文段包含FIN标志,因此它是一个结束报文段。也就是说client端请求关闭连接,这个TCP报文段和同步报文段一样包含一个序号值。
第二次挥手即server端接收到了第一个结束报文段,并发送一个TCP报文段来确认接收到。这个报文段把client发送来的序号值加一返回。
第三次挥手则是用于server端发送给client端的TCP结束报文段,告诉它我这边也结束连接。server端会把自己的序号值发送给client端。
第四次挥手则是client端确认收到server端的结束报文段。把server端发来的序号值加一发送给server端。
这个过程就是TCP服务断开连接时的四次挥手。

为什么是三次握手和四次挥手

说完了建立连接的三次握手和四次挥手肯定有人会问为什么非要三次握手和四次挥手。

三次握手的目的是为了防止已失效的连接请求报文段突然又传送到了服务端。具体来说就是client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。

而为什么是四次挥手就更好理解了。因为TCP是全双工模式,接收到client端的FIN时意味着将没有数据再发过来,但是不代表server端没有数据再发向client端。所以要有两次结束报文段的发送和确认,client端和server端各一次。

图解

图片来自《Linux高性能服务器编程》
关于如何理解TCP的三次握手与四次挥手
ernest-laptop为client端,Kongming20为server端。
seq为ISN序号值,ack为确认序号值。

形象化理解

三次握手:
A:“喂,你听得到吗?”
B:“我听得到呀,你听得到我吗?”应答与请求同时发出
A:“我能听到你,今天balabala……”

再设想一下只有两次握手或者四次握手的情况
两次握手:
A:“喂,你听得到吗?”
B:“我听得到呀,你听得到吗?”
A:“今天balbala…”
B:“…谁在说话?”

四次握手:
A:“喂,你听得到吗?”
B:“我听得到呀,你听得到我吗?”
A:“我能听到你,你能听到我吗?”
B:“你是瓜皮么?”

四次挥手:
A:“喂,我不说了。”
B:“我知道了。等下,上一句还没说完。Balabala……”
B:”好了,说完了,我也不说了。”
A:”我知道了。”
A等待一段时间,保证B收到了消息,否则重说一次”我知道了”