浏览器 TCP 三握&四挥

132 阅读3分钟

三次握手

为什么需要三次握手,两次不行吗?

  • 第一次握手:客户端发送网络包,服务端收到

    • 客户端的发送能力、服务端的接收能力是正常的
  • 第二次握手:服务端发包,客户端收到了

    • 服务端的接收、发送能力,客户端的接收、发送能力是正常的
  • 第三次握手:客户端发包,服务端收到了

    • client 第一个连接请求报文段在某个网络节点滞留 => 延误到达 server

      • 失效的报文段让 server 认为是 client 再次发出的新的连接请求

      • serverclient 发出确认报文段,同意建立连接

    • 不采用 “三次握手”

      • 只要 server 发出确认,就建立新连接

      • client 没有建立连接的请求,不理 server 的确认,也不会向 server 发送数据

      • server 却以为新的运输连接已经建立,并一直等待 client 发来数据

      • server => 浪费资源

    • client 不会向 server 的确认发出确认,server 由于收不到确认,就知道 client 并没有要求建立连接

TCP连接关闭时进行四次挥手过程

记忆

  • 客户端:“你好,我这边没有数据要传了,我要关闭咯。”

  • 服务端:“收到~我看一下我这边有没数据要传的。”

  • 服务端:“我这边也没有数据要传啦,我们可以关闭连接咯~”

  • 客户端:“ok~”

详细

  • 第一次挥手

    • A 认为数据发送完成 => 向 B 发送连接释放请求

      • 该请求只有报文头

        • 头中携带的主要参数为: FIN=1,seq=u
    • A 将进入 FIN-WAIT-1 状态

    • PS1:FIN=1 :个连接释放请求

    • PS2:seq=u,u-1 :A 向 B 发送的最后一个字节的序号

  • 第二次挥手

    • B 收到连接释放请求 => 通知相应的应用程序: A 向 B 这个方向的连接已经释放

    • B 进入 CLOSE-WAIT 状态,并向 A 发送连接释放的应答

    • 其报文头包含: ACK=1,seq=v,ack=u+1。

    • PS1:ACK=1:除 TCP 连接请求报文段以外,TCP 通信过程中所有数据报的 ACK 都为 1,表示应答

    • PS2:seq=v,v-1 是 B 向 A 发送的最后一个字节的序号

    • PS3:ack=u+1 表示希望收到从第 u+1 个字节开始的报文段,并且已经成功接收了前 u 个字节

    • A 收到该应答,进入 FIN-WAIT-2 状态,等待 B 发送连接释放请求

    • 第二次挥手完成后

      • A 到 B 方向的连接已经释放,B 不会再接收数据,A 也不会再发送数据

      • B 到 A 方向的连接仍然存在,B 可以继续向 A 发送数据

  • 第三次挥手

    • B 向 A 发完所有数据后,向 A 发送连接释放请求

    • 请求头:`FIN=1,ACK=1,seq=w,ack=u+1

    • B便进入 LAST-ACK `状态

  • 第四次挥手

    • A 收到释放请求后,向 B 发送确认应答

    • A 进入 TIME-WAIT 状态,该状态会持续 2MSL 时间,若该时间段内没有 B 的重发请求的话,就进入 CLOSED 状态,撤销 TCB

    • 当 B 收到确认应答后,也便进入 CLOSED 状态,撤销 TCB

  • 为什么 A 要先进入 TIME-WAIT 状态,等待 2MSL 时间后才进入 CLOSED 状态?

    • 保证 B 能收到 A 的确认应答

    • 若 A 发完确认应答后直接进入 CLOSED 状态,那么如果该应答丢失,B 等待超时后就会重新发送连接释放请求,但此时 A 已经关闭了,不会作出任何响应,因此 B 永远无法正常关闭

链接:juejin.cn/post/723356…