0
点赞
收藏
分享

微信扫一扫

20230502 - 二叉树1 | 二叉树理论基础、二叉树的递归遍历

boom莎卡拉卡 2023-05-08 阅读 50

文章目录

TCP 四次挥手过程是怎样的?

为什么挥手需要四次?

  • 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
  • 服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
  • 在特定情况下,四次挥手是可以变成三次挥手的

第一次挥手丢失了,会发生什么?

  • 当客户端(主动关闭方)调用 close 函数后,就会向服务端发送 FIN 报文,试图与服务端断开连接,此时客户端的连接进入到 FIN_WAIT_1 状态。
  • 如果能及时收到服务端(被动关闭方)的 ACK,则会很快变为 FIN_WAIT2状态。

第二次挥手丢失了,会发生什么?

  • 当服务端收到客户端的第一次挥手后,就会先回一个 ACK 确认报文,此时服务端的连接进入到 CLOSE_WAIT 状态。

第三次挥手丢失了,会发生什么?

  • 当服务端(被动关闭方)收到客户端(主动关闭方)的 FIN 报文后,内核会自动回复 ACK,同时连接处于 CLOSE_WAIT 状态,顾名思义,它表示等待应用进程调用 close 函数关闭连接。
  • 服务端处于 CLOSE_WAIT 状态时,必须由进程主动调用 close 函数,来触发服务端发送 FIN 报文,同时连接进入 LAST_ACK 状态,等待客户端返回 ACK 来确认连接关闭。

第四次挥手丢失了,会发生什么?

  • 当客户端收到服务端的第三次挥手的 FIN 报文后,就会回 ACK 报文,也就是第四次挥手,此时客户端连接进入 TIME_WAIT 状态

为什么 TIME_WAIT 等待的时间是 2MSL?

  • MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
  • 因为 TCP 报文基于是 IP 协议的,而 IP 头中有一个 TTL 字段,是 IP 数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减 1,当此值为 0 则数据报将被丢弃,同时发送 ICMP 报文通知源主机。
  • MSL 与 TTL 的区别: MSL 的单位是时间,而 TTL 是经过路由跳数。

为什么需要 TIME_WAIT 状态?

  • 主动发起关闭连接的一方,才会有 TIME-WAIT 状态。
  • 需要 TIME-WAIT 状态,主要是两个原因:
    • 防止历史连接中的数据,被后面相同四元组的连接错误的接收;
    • 保证「被动关闭连接」的一方,能被正确的关闭;

TIME_WAIT 过多有什么危害?

  • 第一是占用系统资源,比如文件描述符、内存资源、CPU 资源、线程资源等;
  • 第二是占用端口资源,端口资源也是有限的,一般可以开启的端口为 32768~61000,也可以通过 net.ipv4.ip_local_port_range参数指定范围。
    • 如果客户端(主动发起关闭连接方)的 TIME_WAIT 状态过多,占满了所有端口资源,那么就无法对「目的 IP+ 目的 PORT」都一样的服务端发起连接了
    • 如果服务端(主动发起关闭连接方)的 TIME_WAIT 状态过多,并不会导致端口资源受限,但是 TCP 连接过多,会占用系统资源,比如文件描述符、内存资源、CPU 资源、线程资源等。

服务器出现大量 TIME_WAIT 状态的原因有哪些?

  • TIME_WAIT 状态是主动关闭连接方才会出现的状态,所以如果服务器出现大量的 TIME_WAIT 状态的 TCP 连接,就是说明服务器主动断开了很多 TCP 连接。
  • 什么场景下服务端会主动断开连接呢?
    • 第一个场景:HTTP 没有使用长连接
    • 第二个场景:HTTP 长连接超时
    • 第三个场景:HTTP 长连接的请求数量达到上限

服务器出现大量 CLOSE_WAIT 状态的原因有哪些?

  • CLOSE_WAIT 状态是「被动关闭方」才会有的状态,而且如果「被动关闭方」没有调用 close 函数关闭连接,那么就无法发出 FIN 报文,从而无法使得 CLOSE_WAIT 状态的连接转变为 LAST_ACK 状态。
  • 当服务端出现大量 CLOSE_WAIT 状态的连接的时候,说明服务端的程序没有调用 close 函数关闭连接。

如果已经建立了连接,但是客户端突然出现故障了怎么办?

  • 客户端如果发生了宕机,或者断电的场景。如果服务端一直不会发送数据给客户端,那么服务端是永远无法感知到客户端宕机这个事件的,也就是服务端的 TCP 连接将一直处于 ESTABLISH 状态,占用着系统资源。
  • 为了避免这种情况,TCP 有个保活机制
    • 定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。
  • TCP 保活的这个机制检测的时间是有点长,可以在应用层实现一个心跳机制。
    • web 服务软件一般都会提供keepalive_timeout参数,用来指定 HTTP 长连接的超时时间。如果设置了 HTTP 长连接的超时时间是 60 秒,web 服务软件就会启动一个定时器,如果客户端在完成一个 HTTP 请求后,在 60 秒内都没有再发起新的请求,定时器的时间一到,就会触发回调函数来释放该连接。

如果已经建立了连接,但是服务端的进程崩溃会发生什么?

  • TCP 的连接信息是由内核维护的,所以当服务端的进程崩溃后,内核需要回收该进程的所有 TCP 连接资源,于是内核会发送第一次挥手 FIN 报文,后续的挥手过程也都是在内核完成,并不需要进程的参与,所以即使服务端的进程退出了,还是能与客户端完成 TCP 四次挥手的过程。

文章参考:https://xiaolincoding.com/

举报

相关推荐

0 条评论