Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题( 七 )


正常流程
正常流程:

  • 当服务端接收到客户端的 SYN 报文时 , 会将其加入到内核的「 SYN 队列」;
  • 接着发送 SYN + ACK 给客户端 , 等待客户端回应 ACK 报文;
  • 服务端接收到 ACK 报文后 , 从「 SYN 队列」移除放入到「 Accept 队列」;
  • 应用通过调用 accpet socket 接口 , 从「 Accept 队列」取出的连接 。

Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
本文插图
应用程序过慢
应用程序过慢:
  • 如果应用程序过慢时 , 就会导致「 Accept 队列」被占满 。

Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
本文插图
受到 SYN 攻击
受到 SYN 攻击:
  • 如果不断受到 SYN 攻击 , 就会导致「 SYN 队列」被占满 。
tcp_syncookies 的方式可以应对 SYN 攻击的方法:
net.ipv4.tcp_syncookies = 1

Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
本文插图
tcp_syncookies 应对 SYN 攻击
  • 当 「 SYN 队列」满之后 , 后续服务器收到 SYN 包 , 不进入「 SYN 队列」;
  • 计算出一个 cookie 值 , 再以 SYN + ACK 中的「序列号」返回客户端 ,
  • 服务端接收到客户端的应答报文时 , 服务器会检查这个 ACK 包的合法性 。 如果合法 , 直接放入到「 Accept 队列」 。
  • 最后应用通过调用 accpet socket 接口 , 从「 Accept 队列」取出的连接 。

Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
本文插图
TCP 连接断开TCP 四次挥手过程和状态变迁
天下没有不散的宴席 , 对于 TCP 连接也是这样 ,TCP 断开连接是通过四次挥手方式 。
双方都可以主动断开连接 , 断开连接后主机中的「资源」将被释放 。
Java:吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
本文插图
客户端主动关闭连接 —— TCP 四次挥手
  • 客户端打算关闭连接 , 此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文 , 也即 FIN 报文 , 之后客户端进入 FIN_WAIT_1 状态 。
  • 服务端收到该报文后 , 就向客户端发送 ACK 应答报文 , 接着服务端进入 CLOSED_WAIT 状态 。
  • 客户端收到服务端的 ACK 应答报文后 , 之后进入 FIN_WAIT_2 状态 。
  • 等待服务端处理完数据后 , 也向客户端发送 FIN 报文 , 之后服务端进入 LAST_ACK 状态 。
  • 客户端收到服务端的 FIN 报文后 , 回一个 ACK 应答报文 , 之后进入 TIME_WAIT 状态
  • 服务器收到了 ACK 应答报文后 , 就进入了 CLOSE 状态 , 至此服务端已经完成连接的关闭 。
  • 客户端在经过 2MSL 一段时间后 , 自动进入 CLOSE 状态 , 至此客户端也完成连接的关闭 。
你可以看到 , 每个方向都需要一个 FIN 和一个 ACK , 因此通常被称为四次挥手 。
这里一点需要注意是:主动关闭连接的 , 才有 TIME_WAIT 状态 。
为什么挥手需要四次?
再来回顾下四次挥手双方发 FIN 包的过程 , 就能理解为什么需要四次了 。