什么是TCP三次握手和四次挥手【重点学习系列---干货十足--一文详解】

引言

本文将会从一个爱情的故事开始,着力从什么是三次握手、为什么是三次而不是俩次或者四次、TCP关闭的过程、为什么要四次挥手、而不是三次、为什么最后是2MSL、什么是2MSL这些问题展开分析,详解,让你一文弄懂三次握手、四次挥手。

谈谈我对TCP三次握手和四次挥手的理解

开局一张图,内容全靠编,图来 ↘

什么是TCP三次握手和四次挥手【重点学习系列---干货十足--一文详解】

小爱同学(故事来喽)ʚ ɞ:
  • Jack:我要挂了哦
  • Rose:等哈,我还要敷面膜
  • Rose:我敷完了,现在可以挂了
  • Jack:我舍不得挂,你挂吧
  • Rose:好吧,我挂了
  • Jack:等了2MSL听见嘟嘟嘟的声音后挂断

一、三次握手讲解

三次握手之所以是三次,是为了保证client和server均让对方知道自己的接收和发送能力没问题而保证的最小的次数。

  • 第一次client => server 只能server判断出client具备发送能力
    • 客户端发给服务器,发了一个字段叫syn后面会带一个标志位可能是1、2、3。
    • 比如我建立一个TCP连接,syn=1。如果我又建立了第二个TCP连接,syn=2,这个值是唯一得值,其代表我当前次TCP连接。
    • 服务器由这个syn值知道客户端要求联机。(客户端:我要连接你)
  • 第二次 server => client client就可以判断出server具备发送和接受能力。
    • 服务端收到联机请求后要求确认信息,向客户端发送了一个字段(ack+syn(这个是客户端发来的字段----联机信息))。
    • 此时客户端就知道服务器已经充分做好了准备,可以联机了。(服务端,我已就位,你来连吧)
  • 第三次:此时client还需让server知道自己接收能力没问题于是就有了第三次 第三次 client => server 双方均保证了自己的接收和发送能力没有问题
    • 只有一次的话,客户端准备好了告诉服务端我要发请求了,只是代表客户端准备好了,但是服务端一定准备好了吗?不一定,因为每个服务器都要最大请求处理次数,当其到达最大次数,就没有办法处理了,所以一定要服务期准备好。
    • 所以有了第二次,当服务器准备好了就要告诉客户端,ask+syn就是告诉客户端我已准备好,这样的话不就需要俩次吗?为什么要有三次呢?
    • 举个例子,加入服务器告诉了客户端我已准备好,客户端知道了,万一客户端想约会去了,给溜了怎么办,服务器还在那里苦苦的、痴情的等待着,这这样子肯定不行啊,这种会造成服务器的资源大大的浪费。
    • 所以服务器会等客户端再次确认是没有问题的,服务器才会真正的建立联系,如果客户端没有确认,那么服务器就认为客户端没有准备好,是不会和他建立联系的。
      其中,为了保证后续的握手是为了应答上一个握手,每次握手都会带一个标识 syn,后续的ACK都会对这个syn进行加一来进行确认。

二、为什么http建立连接需要三次握手,不是两次或四次?

  • 三次是最少的安全次数,确保双方都准备充分,不会存在任何一方突然断开连接。
  • 两次不安全,四次浪费资源;

三、什么是四次挥手?

四次挥手
  • 第一次挥手:浏览器发送给服务器,告诉服务器请求报文发送完毕
  • 第二次挥手:服务器发送给浏览器,告诉浏览器请求报文接受完毕,可以等待断开
  • 第三次挥手:服务器发送给浏览器,告诉浏览器响应报文发送完毕
  • 第四次挥手:浏览器发送给服务器,告诉服务器响应报文接受完毕,可以断开连接
  • 最后服务器断开连接,浏览器断开连接
四次挥手详细过程(TCP关闭连接过程)☛结合开局图解
  1. Client向Server发送FIN包,表示Client主动要关闭连接,然后进入FIN_WAIT_1状态,等待Server返回ACK包。此后Client不能再向Server发送数据,但能读取数据。
  2. Server收到FIN包后向Client发送ACK包,然后进入CLOSE_WAIT状态,此后Server不能再读取数据,但可以继续向Client发送数据。
  3. Client收到Server返回的ACK包后进入FIN_WAIT_2状态,等待Server发送FIN包。
  4. Server完成数据的发送后,将FIN包发送给Client,然后进入LAST_ACK状态,等待Client返回ACK包,此后Server既不能读取数据,也不能发送数据。
  5. Client收到FIN包后向Server发送ACK包,然后进入TIME_WAIT状态,接着等待足够长的时间(2MSL)以确保Server接收到ACK包,最后回到CLOSED状态,释放网络资源。
  6. Server收到Client返回的ACK包后便回到CLOSED状态,释放网络资源。

四、为什么要四次挥手?

☞四次挥手的目的:为了断开连接
  • 发送请求断开需要俩次挥手:浏览器讲请求报文发送给服务器
  • 返回响应断开需要俩次挥手:服务器将响应报文发送给浏览器
☞什么是全双工信道?
  • TCP是全双工信道,就是客户端与服务端建立两条通道。
  • 通道1:客户端的输出连接服务端的输入;
  • 通道2:客户端的输入连接服务端的输出。
  • 两个通道可以同时工作:客户端向服务端发送信号的同时服务端也可以向客户端发送信号。所以关闭双通道的时候就是这样:
    客户端:我要关闭输入通道了。 服务端:好的,你关闭吧,我这边也关闭这个通道。
    服务端:我也要关闭输入通道了。 客户端:好的你关闭吧,我也把这个通道关闭。
☞问题: 4次挥手中,如果没有(稍等,还有最后一个包),那是不是就是三次挥手?

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭,所以即使没有最后一个包,也需要先回复断开连接的请求,然后再发送关闭请求

五、什么是 MSL、 为什么是2MSL

  • Maximum Segment Lifetime,译为“报文最大生存时间”。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等

  • 2MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态

  • 当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间。

  • 等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。

  • TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。 当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。


六、总结

  • 总体来说,TCP三次握手、四次挥手算是明白了,但是如果深究背后的原理,还是会牵扯出来很多的知识点,比如几层http协议、请求报文、响应报文、HTTP缓存机制与原理等,后续再逐一详解吧。
  • 愿你在这个代码繁杂、头发渐秃的编码世界里,可以温暖自己,坚持学习。

使人疲惫的不是远方的高山,而是鞋子里的一粒沙子。——伏尔泰

『传送门』☛HTTP缓存机制与原理详解