前端那些事

vuePress-theme-reco chenpeng    2020 - 2021
前端那些事 前端那些事

Choose mode

  • dark
  • auto
  • light
首页
文章目录
  • Browser
  • CSS
  • ES6
  • JavaScript
  • Network
  • TypeScript
  • Vue
  • Vue3
  • Webpack
标签
时间轴
GitHub
author-avatar

chenpeng

85

Article

25

Tag

首页
文章目录
  • Browser
  • CSS
  • ES6
  • JavaScript
  • Network
  • TypeScript
  • Vue
  • Vue3
  • Webpack
标签
时间轴
GitHub
  • Network

    • TCP三次握手与四次挥手
    • HTTPS
    • OSI参考模型
    • HTTP各版本
    • TCP与UDP

TCP三次握手与四次挥手

vuePress-theme-reco chenpeng    2020 - 2021

TCP三次握手与四次挥手

chenpeng 2020-11-29 TCP

①、TCP 报文格式

20180717201939345
  1. TCP 报头中的源端口号和目的端口号与 IP 数据报中的源 IP 和目的 IP 唯一确定一条 TCP 连接,TCP 在发送数据前必须在彼此间建立连接
  2. 报文主要段的意思:
    1. 序号(seq):表示发送的数据字节流,确保TCP传输有序,对每个字节编号
    2. 确认号(ack):期待收到对方下一个报文段的第一个数据字节的序号,当前报文段最后一个字节的序号加1即为确认号
    3. 确认(ACK):当 ACK = 1时,确认号有效;当 ACK = 0时,确认号无效
    4. 同步(SYN):连接建立请求时同步序号,当 SYN = 1时,表示请求连接
    5. 终止(FIN):用来释放一个连接,当 FIN = 1时,表示此报文段的发送方的数据已经发送完毕,并要求释放连接

②、三次握手过程

建立 TCP 连接时,需要客户端和服务端共发送3个包

  1. 第一次握手:客户端发送请求标志 SYN = 1 和初始序号 seq = x ,请求建立连接,客户端进入 SYN-SENT 状态
  2. 第二次握手:服务端发送请求标志 SYN = 1,确认标志 ACK = 1,自己的序号 seq = y,客户端的确认序号 ack = x + 1,服务端进入 SYN-RCVD 状态
  3. 第三次握手:客户端发送确认标志 ACK = 1,自己的序号 seq = x + 1,服务端的确认序号 ack = y + 1,发送完毕后,客户端和服务端进入 ESTABLISHED(TCP 连接成功)状态,完成三次握手

三次握手过程分析

  1. 第一次:客户端发送请求到服务端,服务端知道客户端发送,自己接收正常
  2. 第二次:服务端发送请求到客户端,客户端知道自己发送、接收正常,服务端发送、接收正常
  3. 第三次:客户端发送请求到服务端,服务端知道客户端发送、接收正常,自己发送、接收也正常

综上所述,握手三次才能使双方都知道自己和对方发送和接收都正常

③、四次挥手过程

释放 TCP 连接时,需要客户端和服务端共发送4个包

  1. 第一次挥手:客户端发送终止标志 FIN = 1,自己的序号 seq = u,客户端进入 FIN-WAIT-1 状态
  2. 第二次挥手:服务端接收到客户端的连接释放报文,发送确认标志 ACK = 1,自己的序号 seq = v,客户端的确认号 ack = u + 1,服务端进入 CLOSE-WAIT 状态。这时候处于半关闭状态,客户端已经不再发送数据了,但是服务端若要发送数据,客户端依然要接收
  3. 第三次挥手:客户端收到服务端的确认结果后,进入 FIN-WAIT-2 状态。服务端发送 终止标志 FIN = 1,确认标志 ACK = 1,自己的序号 seq = w,客户端的确认号 ack = u + 1,服务端进入 LAST-ACK(最后确认)状态,等待客户端的确认
  4. 第四次挥手:客户端接收到服务端的连接释放报文,发送确认标志 ACK = 1,自己的序号 seq = u + 1,服务端的确认号 ack = w + 1,客户端进入 TIME-WAIT(时间等待)状态。客户端必须经过2MSL(报文最大生存事件)后,才能进入 CLOSED 状态。而服务端只要接收到客户端的确认后,立即进入 CLOSED 状态

四次挥手分析

  1. 第一次:客户端请求释放连接
  2. 第二次:服务端确认客户端的释放连接
  3. 第三次:服务端请求释放连接
  4. 第四次:客户端确认服务端的释放连接

④、其他问题

为什么建立连接不是两次或四次握手?

  1. 不是两次的原因:无法确定客户端的接收能力
  2. 不是四次的原因:建立连接三次握手足够了,再多次用处不大

为什么连接的时候是三次握手,释放的时候是四次挥手?

  1. 三次握手时,服务端把 SYN 和 ACK 放在一起发送给了客户端
  2. 四次挥手时,服务端收到客户端的 FIN 报文时,仅仅表示客户端不再发送数据了但是还能接收数据,必须等到所有的报文都发送完毕了,才能发送 FIN,因此先发一个 ACK 表示已经收到客户端的 FIN,延迟一段时间再发送 FIN

为什么客户端最后还要等待2MSL?

  • 客户端需要保证最后一次发送的 ACK 报文到达服务端,如果服务端未收到,可以请求客户端重新发送,这样客户端还有时间重发,重启 2MSL 计时
  • 1 个 MSL 确保四次挥手中主动关闭方最后的 ACK 报文最终能达到对端
  • 1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报文可以到达