三次握手和四次挥手是一种协议,TCP在传输之前会进行三次沟通,一般称为“三次握手”,传完数据断开的时候要进行四次沟通,一般称为“四次挥手”。
三次握手
例子:
为什么要这样去设计呢?这是为了保证双方的连接有效性,就好比你和女朋友打电话聊天,你拿起了电话,先要说一句“喂?”,这一句是询问对方是否存在,女朋友会回一声“喂,你是谁?”(此处不考虑来电显示。。。)这一句是证明自己存在并且抛出了一个问题,你答:“我是你男朋友”,这样进行了三次沟通,双方都确认了双方的连接正常,接下来,就可以聊天了,这种方式在TCP种就是三次握手协议。
针对这个方式,有人要问了,女朋友为什么要多问一句你是谁然后等待你的应答呢?也就是说,为什么是三次握手而不是两次握手呢?
TCP三次握手
这些比喻映照到真正的TCP上就是客户端给服务器端发送了SYN报文(相当于“喂?”),服务器端接收到之后回复了SYN+ACK报文(相当于“喂,你是谁?”),客户端再向服务器端发送ACK报文(相当于“我是你男朋友”),然后双方就正式建立了连接,可以开始进行数据交互了。
针对上面的问题,为什么不是两次握手而是三次握手,这是因为如果客户端第一次发送的SYN报文延迟了,客户端重新发送了一次,这次没有延迟,双方建立了连接开始数据交互。这个时候,刚才延迟的SYN报文发到了服务器端,服务器以为是客户端又发了一次,于是又对客户端做出了回应,然后等待客户端的回应,这个时候客户端根本不会对这次服务器端的报文做出响应,于是服务器端一直等着客户端回应,客户端一直不回应,这样会造成服务器端的资源浪费。
四次挥手
例子:
与之相对,当你和女朋友聊天结束的时候,出于礼貌,你要先说:“我要挂电话了啊”,女朋友得知你的结束聊天意图了,但是如果她此时还挂不了电话,她还没准备好挂电话怎么办呢?如果你说了一句要挂电话然后就把电话挂了,那是很不礼貌的行为,所以,为了应对女朋友没法挂电话这种情况的发生,需要进行四次挥手。女朋友在得知要挂电话的意图的时候,会先回一句:“等等”,然后等她准备好挂电话的时候,她会给你发送一句:“可以挂了”,然后她就挂了电话。这个时候你听到了这句,于是再回一句:“拜拜”,然后等待了几秒钟发现女朋友那边没声音了,知道她是挂了电话了。至此,聊天结束。
TCP四次挥手
在断开连接的时候,客户端向服务器端先发送FIN报文(“我要挂电话了啊”),服务器端回复ACK报文(“等等”),然后等服务器准备好了之后,向客户端发送FIN报文(“可以挂了”),客户端回复服务器端ACK报文(“拜拜”),然后客户端等待一段时间之后得不到回应就知道服务器端已经断开了连接,至此,这次连接结束。
流程图: