当前位置: 首页 > news >正文

计算机网络(五):三次握手和四次挥手,TCP,UDP,TIME-WAIT,CLOSE-WAIT,拥塞避免,

文章目录

  • 零. TCP和UDP的区别以及TCP详解
    • TCP是如何保证可靠性的
    • TCP超时重传的原理
    • TCP最大连接数限制
    • TCP流量控制和拥塞控制
      • 流量控制
      • 拥塞控制
    • TCP粘包问题
  • 一、三次握手和四次挥手
  • 二、为什么要进行三次握手?两次握手可以吗?
  • 三、为什么要进行四次挥手?三次可以吗?
  • 四、第二次握手传回来了ACK,为什么还要传回SYN?
  • 五. CLOSE-WAIT和TIME-WAIT的状态和意义
  • 六. TIME-WAIT为什么是2MSL
  • 七. 有很多TIME-WAIT状态要如何解决
  • 八. 有很多CLOSE-WAIT状态要如何解决


零. TCP和UDP的区别以及TCP详解

请添加图片描述

TCP是如何保证可靠性的

  1. 数据分块:应用数据被分割成 TCP 认为最适合发送的数据块。
  2. 序列号和确认应答:TCP 给发送的每一个包进行编号,在传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答,即发送 ACK 报文,这个 ACK 报文当中带有对应的确认序列号,告诉发送方成功接收了哪些数据以及下一次的数据从哪里开始发。除此之外,接收方可以根据序列号对数据包进行排序,把有序数据传送给应用层,并丢弃重复的数据。
  3. 校验和: TCP 将保持它首部和数据部分的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到报文段的检验和有差错,TCP 将丢弃这个报文段并且不确认收到此报文段。
  4. 流量控制:TCP 连接的双方都有一个固定大小的缓冲空间,发送方发送的数据量不能超过接收端缓冲区的大小。当接收方来不及处理发送方的数据,会提示发送方降低发送的速率,防止产生丢包。TCP 通过滑动窗口协议来支持流量控制机制。
  5. 拥塞控制:当网络某个节点发生拥塞时,减少数据的发送。
  6. ARQ协议:也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
  7. 超时重传:当 TCP 发出一个报文段后,它启动一个定时器,等待目的端确认收到这个报文段。如果超过某个时间还没有收到确认,将重发这个报文段。

TCP超时重传的原理

发送方在发送一次数据后就开启一个定时器,在一定时间内如果没有得到发送数据报的ACK报文,那么就重新发送数据,在达到一定次数还没有成功的话就放弃重传并发送一个复位信号。其中超时时间的计算是超时的核心,而定时时间的确定往往需要进行适当的权衡,因为当定时时间过长会造成网络利用率不高,定时时间过短会造成多次重传,使得网络阻塞。在TCP连接的过程中,会参考当前的网络状况从而找到一个合适的超时时间。

TCP最大连接数限制

  1. Client 最大 TCP 连接数
    client 在每次发起 TCP 连接请求时,如果自己并不指定端口的话,系统会随机选择一个本地端口(local port),该端口是独占的,不能和其他 TCP 连接共享。TCP 端口的数据类型是 unsigned short,因此本地端口个数最大只有 65536,除了端口 0不能使用外,其他端口在空闲时都可以正常使用,这样可用端口最多有 65535 个。

  2. Server最大 TCP 连接数
    server 通常固定在某个本地端口上监听,等待 client 的连接请求。不考虑地址重用(Unix 的 SO_REUSEADDR 选项)的情况下,即使 server 端有多个 IP,本地监听端口也是独占的,因此 server 端 TCP 连接 4 元组中只有客户端的 IP 地址和端口号是可变的,因此最大 TCP 连接为客户端 IP 数 × 客户端 port 数,对 IPV4,在不考虑 IP 地址分类的情况下,最大 TCP 连接数约为 2 的 32 次方(IP 数)× 2 的 16 次方(port 数),也就是 server 端单机最大 TCP 连接数约为 2 的 48 次方。

TCP流量控制和拥塞控制

流量控制

流量控制就是让发送方的发送速率不要太快,让接收方来得及接收。如果接收方来不及接收发送方发送的数据,那么就会有分组丢失。在TCP中利用可变长的滑动窗口机制可以很方便低在TCP连接上实现对发送方的流量控制。 实现方式是接收端返回的ACK中会包含自己的接收端的滑动窗口大小,以控制发送方此次发送的数据量大小。

如果接收方的滑动窗口满了,基于TCP流量控制的滑动窗口协议,接收方返回给发送方的接收窗口大小为 0,此时发送方会等待接收方发送的窗口大小直到变为非 0 为止,然而,接收方回应的 ACK 包是存在丢失的可能的,为了防止双方一直等待而出现死锁情况,此时就需要坚持计时器来辅助发送方周期性地向接收方查询,以便发现窗口是否变大。

拥塞控制

拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况。常用的解决方法有:慢开始和拥塞避免、快重传和快恢复。

  1. 慢开始
    当发送方开始发送数据时,由于一开始不知道网络负荷情况,如果立即将大量的数据字节传输到网络中,那么就有可能引起网络拥塞。一个较好的方法是在一开始发送少量的数据先探测一下网络状况,即由小到大的增大发送窗口(拥塞窗口 cwnd)。慢开始的慢指的是初始时令 cwnd为 1,即一开始发送一个报文段。如果收到确认,则 cwnd = 2,之后每收到一个确认报文,就令 cwnd = cwnd* 2。

但是,为了防止拥塞窗口增长过大而引起网络拥塞,另外设置了一个慢开始门限 ssthresh。
① 当 cwnd < ssthresh 时,使用上述的慢开始算法;
② 当 cwnd > ssthresh 时,停止使用慢开始,转而使用拥塞避免算法;
③ 当 cwnd == ssthresh 时,两者均可。

  1. 拥塞避免

拥塞控制是为了让拥塞窗口 cwnd 缓慢地增大,即每经过一个往返时间 RTT (往返时间定义为发送方发送数据到收到确认报文所经历的时间)就把发送方的 cwnd 值加 1,通过让 cwnd 线性增长,防止很快就遇到网络拥塞状态。

当网络拥塞发生时,让新的慢开始门限值变为发生拥塞时候的值的一半,并将拥塞窗口置为 1 ,然后再次重复两种算法(慢开始和拥塞避免),这时一瞬间会将网络中的数据量大量降低。

  1. 快重传
    快重传算法要求接收方每收到一个失序的报文就立即发送重复确认,而不要等到自己发送数据时才捎带进行确认,假定发送方发送了 Msg 1 ~ Msg 4 这 4 个报文,已知接收方收到了 Msg 1,Msg 3 和 Msg 4 报文,此时因为接收到收到了失序的数据包,按照快重传的约定,接收方应立即向发送方发送 Msg 1 的重复确认。 于是在接收方收到 Msg 4 报文的时候,向发送方发送的仍然是 Msg 1 的重复确认。这样,发送方就收到了 3 次 Msg 1 的重复确认,于是立即重传对方未收到的 Msg 报文。由于发送方尽早重传未被确认的报文段,因此,快重传算法可以提高网络的吞吐量。

  2. 快恢复
    快恢复算法是和快重传算法配合使用的,该算法主要有以下两个要点:

① 当发送方连续收到三个重复确认,执行乘法减小,慢开始门限 ssthresh 值减半;

② 由于发送方可能认为网络现在没有拥塞,因此与慢开始不同,把 cwnd 值设置为 ssthresh 减半之后的值,然后执行拥塞避免算法,线性增大 cwnd。

TCP粘包问题

为什么会出现TCP粘包和拆包?

  1. 当发送方写入的数据大于socket的缓冲区的大小的时候需要拆包。或者当TCP报文的数据部门大小大于MSS(最大报文长度)的时候将会出现拆包。
  2. 当发送方发送的数据太快,接收方处理数据的速度赶不上发送端的速度的时候将会发生粘包。

解决方案:

  1. 在消息的头部添加消息长度字段,服务端获取消息头的时候解析消息长度,然后向后读取相应长度的内容。
  2. 设置消息边界,也可以理解为分隔符,服务端从数据流中按消息边界分离出消息内容,一般使用换行符。

一、三次握手和四次挥手

三次握手
四次挥手

二、为什么要进行三次握手?两次握手可以吗?

第一次握手:客户端只是发送处请求报文段,什么都无法确认,而服务器可以确认自己的接收能力和对方的发送能力正常;
第二次握手:客户端可以确认自己发送能力和接收能力正常,对方发送能力和接收能力正常;
第三次握手:服务器可以确认自己发送能力和接收能力正常,对方发送能力和接收能力正常;
可见三次握手才能让双方都确认自己和对方的发送和接收能力全部正常,这样就可以愉快地进行通信了。

一方面,如果只有第二次握手,服务端发给客服端的包丢了之后,服务端就直接建立了连接,然后一直傻等,从而造成服务器系统调用超时返回。
另一个方面,TCP 实现了可靠的数据传输,原因之一就是 TCP 报文段中维护了序号字段和确认序号字段,通过这两个字段双方都可以知道在自己发出的数据中,哪些是已经被对方确认接收的。这两个字段的值会在初始序号值得基础递增,如果是两次握手,只有发送方(比如客户端)的初始序号可以得到确认,而另一方的初始序号则得不到确认。

三、为什么要进行四次挥手?三次可以吗?

四次挥手可以被抽象为如下过程:

  1. Client: 请求关闭
  2. Server: 同意该请求
  3. Server: 请求关闭
  4. Client: 同意该请求

考虑以下服务器遭遇的场景,
先同意对方关闭连接,对方无法传输数据;(第二次挥手)
自己若还有数据未发送完,接着发送直至全部发送完毕;
请求自身关闭连接;(第三次挥手)
客户端同意(第四次挥手)

如果说服务器在客户端请求关闭连接的一瞬间已经没有任何数据需要发送了,那么三次挥手应该也是可以的,但是在实际生产环境中这样的情况几乎没有,所以需要服务器先把自己的所有数据发送完毕,因此四次挥手更加稳妥。

或者也可以这么回答:

释放 TCP 连接时之所以需要四次挥手,是因为 FIN 释放连接报文和 ACK 确认接收报文是分别在两次握手中传输的。 当主动方在数据传送结束后发出连接释放的通知,由于被动方可能还有必要的数据要处理,所以会先返回 ACK 确认收到报文。当被动方也没有数据再发送的时候,则发出连接释放通知,对方确认后才完全关闭TCP连接。

四、第二次握手传回来了ACK,为什么还要传回SYN?

ACK是为了告诉客户端发来的数据接收无误,传回SYN是为了把自己的初始序列号同步到客户端。

五. CLOSE-WAIT和TIME-WAIT的状态和意义

CLOSE- WAIT发生在第二次挥手请求发送之后。
在服务器收到了客户端关闭连接的请求并且告诉客户端自己已经成功收到了该请求之后,服务器进入了CLOSE- WAIT状态,然而此时有可能服务端还有一些数据还没有传输完成,CLOSE- WAIT状态就是用来保证服务器在关闭连接之前能够将待发送的所有数据发送完成,因此不能立即关闭连接。

TIME-WAIT发生在第四次挥手的时候,当客户端向服务端发送ACK确认报文后进入该状态。作用有两个

  1. 客户端立即关闭后,立即又用同样的端口握手并建立通信,此时上次的连接残留的数据包会被误认为是最新连接的,造成数据异常,
  2. 客户端直接关闭后,若服务端重新发送 fin 包,客户端就会回应 RST,会报异常,但是其实是没有问题的

六. TIME-WAIT为什么是2MSL

当客户端发出最后的ACK确认报文时,并不能确定服务器能够接收到该段报文。所以客户端在发送完ACK确认报文之后,会设置一个时长为2MSL的计时器。

如果服务器在1MSL后仍然没有收到客户端发送的ACK确认报文,那么它会向客户端重传FIN报文,对客户端而言,从客户端发出ACK报文起,重传的FIN报文的最晚到达时间是2MSL。

若服务器在1MSL内没有收到客户端发出的ACK确认报文,再次向客户端发送FIN释放连接报文。若客户端在2MSL内收到了服务器在此发来的FIN报文,客户端将再次向服务器发出ACK确认报文,并重新开始2MSL的计时。

七. 有很多TIME-WAIT状态要如何解决

服务器可以设置 SO_REUSEADDR 套接字选项来通知内核,如果端口被占用,但 TCP 连接位于 TIME_WAIT 状态时可以重用端口。如果你的服务器程序停止后想立即重启,而新的套接字依旧希望使用同一端口,此时 SO_REUSEADDR 选项就可以避免 TIME-WAIT 状态。
实际上,要建立长连接的话,就需要使用SO_REUSEADDR关键字。

八. 有很多CLOSE-WAIT状态要如何解决

一般来说,系统内不会出现很多CLOSE- WAIT(第二次挥手后服务器出现的状态)。我们可以首先检查一下是不是自己的代码出现了问题,比如查看服务端是否忘记关闭连接。其次我们可以调整系统参数,包括句柄相关参数和TCP/IP的参数,一般一个CLOSE_WAIT会维持至少两个小时。


相关文章:

计算机网络(五):三次握手和四次挥手,TCP,UDP,TIME-WAIT,CLOSE-WAIT,拥塞避免,

文章目录零. TCP和UDP的区别以及TCP详解TCP是如何保证可靠性的TCP超时重传的原理TCP最大连接数限制TCP流量控制和拥塞控制流量控制拥塞控制TCP粘包问题一、三次握手和四次挥手二、为什么要进行三次握手&#xff1f;两次握手可以吗&#xff1f;三、为什么要进行四次挥手&#xf…...

【数据结构】二叉树(C语言实现)

文章目录一、树的概念及结构1.树的概念2.树的相关概念名词3.树的表示4.树在实际中的运用二、二叉树概念及结构1.二叉树的概念2.特殊的二叉树3.二叉树的性质4.二叉树的存储结构三、二叉树链式结构的实现1.结构的定义2.构建二叉树3.二叉树前序遍历4.二叉树中序遍历5.二叉树后序遍…...

高级信息系统项目管理(高项 软考)原创论文——成本管理(2)

1、如果您想了解如何高分通过高级信息系统项目管理师(高项)你可以点击链接: 高级信息系统项目管理师(高项)高分通过经验分享_高项经验 2、如果您想了解更多的高级信息系统项目管理(高项 软考)原创论文,您可以点击链接:...

代码签名即将迎来一波新关注

在数字化高度发展的当下&#xff0c;个人隐私及信息安全保护已经成了大家关注的重点&#xff0c;包括日常使用的电脑软件&#xff0c;手机APP等&#xff0c;由于包含了大量的用户信息&#xff0c;已经成了重点关注对象&#xff0c;任何一个疏忽就可能泄露大量用户信息。所以权威…...

黑盒渗透盲打lampiao

一、查找主机ip&#xff0c;通过Nmap扫描工具排查出我的靶机的IP 为.134 python tools.py ip -i 192.168.12.0 -h 254 -l 1 二、扫描其他端口。 1898 三、查看网站漏洞情况&#xff0c;典型的漏洞特征 Ac扫描漏洞情况&#xff0c;利用典型的漏洞。 四、开始getshell 1、启动M…...

笔记:VLAN及交换机处理详细教程(Tagged, UnTagged and Native VLANS Tutorial)

一、内容来源 本文是对下面这篇文章的总结&#xff0c;写的很全、很细致、干货满满&#xff0c;强力推荐&#xff1a; 《Tagged, UnTagged and Native VLANS Tutorial – A Quick Guide about What they Are?》 二、为什么引入VLAN&#xff1f; 早期设备间通过集线器&#x…...

在字节跳动,造赛博古籍

“你在字节跳动哪个业务&#xff1f;”“古籍数字化。把《论语》《左传》《道德经》这些古籍变成电子版&#xff0c;让大家都能免费看。”没错&#xff0c;除了你熟悉的那些 App&#xff0c;字节跳动还在做一些小众而特别的事情&#xff0c;古籍数字化就是其中之一。在字节跳动…...

Android 12.0设置默认Launcher安装一款Launcher默认Launcher无效的解决方案

1.概述 在12.0的系统rom定制化过程中,在系统中当有多个Launcher的时候,这时候会要求设置默认Launcher,但是在最近的产品开发过程中,发现在设置完默认Launcher以后,在安装个Launcher的时候,会让原来设置的默认Launcher变为空了,就是在系统Settings中的默认应用中,launche…...

数据结构第16周 :( 希尔排序+ 堆排序 + 快速排序 )

目录希尔排序堆排序快速排序希尔排序 【问题描述】给出一组数据&#xff0c;请用希尔排序将其按照从小到大的顺序排列好。 【输入形式】原始数据&#xff0c;以0作为输入的结束&#xff1b;第二行是增量的值&#xff0c;都只有3个。 【输出形式】每一趟增量排序后的结果 【…...

【C++】类和对象

1.面向过程和面向对象初步认识 我们知道&#xff0c;C语言是面向过程的&#xff0c;关注的就是问题解决的过程&#xff1b; C是面向过程和面向对象混编&#xff0c;因为C兼容了C语言&#xff0c;而面向对象关注的不再是问题解决的过程&#xff1b; 而是一件事情所关联的不同…...

Java缓存面试题——Redis应用

文章目录1、为什么要使用Redis做缓存&#xff1f;2、为什么Redis单线程模型效率也能那么高&#xff1f;3、Redis6.0为什么要引入多线程呢&#xff1f;4、Redis常见数据结构以及使用场景字符串&#xff08;String&#xff09;哈希(Hash)列表&#xff08;list&#xff09;集合&am…...

KMP算法详细理解

一、目的1.KMP应用场景&#xff1a;可以解决字符串匹配问题&#xff1b; 在一个串中查找是否出现过另一个串。2.KMP的经典思想就是:当出现字符串不匹配时&#xff0c;可以记录一部分之前已经匹配的文本内容&#xff0c;利用这些信息避免从头再去做匹配。3.KMP算法关键在于&…...

RabbitMQ单节点安装

在学习RabbitMQ之前&#xff0c;必须要把RabbitMQ的环境搭建起来&#xff0c;刚开始学习时&#xff0c;搭建单节点是入门RabbitMQ最方便、最快捷的方式&#xff0c;这篇文章就是介绍如何使用RabbitMQ压缩包的方式搭建一个单节点的RabbitMQ。 在实际项目中&#xff0c;服务器都…...

tomcat 服务的目录结构和tomcat的运行模式

目录 一、tomcat 服务的目录结构解析&#xff1a; 1、tomcat目录结构&#xff1a; bin目录&#xff1a; conf目录&#xff1a; lib目录&#xff1a; logs目录&#xff1a; temp目录&#xff1a; webapps目录&#xff1a; wokr目录&#xff1a; 二、tomcat服务的运行模…...

vector迭代器失效问题

一、迭代器&#xff1a; 迭代器的主要作用就是让算法能够不用关心底层数据结构&#xff0c;其底层实际就是一个指针&#xff0c;或者是对指针进行了封装&#xff0c;比如&#xff1a;vector的迭代器就是原生态指针T* 。因此迭代器失效&#xff0c;实际就是迭代器底层对应指针所…...

2023年排名前茅的十大饭店装修设计!

相信大家都是知道的&#xff0c;饭店装修设计其实是一门很深的学问&#xff0c;只有掌握这门学问才能够打造出来精美的空间&#xff0c;因此饭店装修必须要有专业餐饮设计公司的设计师进行设计。但是在国内饭店装修设计公司那么多&#xff0c;饭店老板要如何选择呢&#xff1f;…...

MFCCA多通道多说话人语音识别模型上线魔搭(ModelScope)

实验室研发的基于多帧跨通道注意力机制&#xff08;MFCCA&#xff09;的多说话人语音识别模型近日上线魔搭&#xff08;ModelScope&#xff09;社区&#xff0c;该模型在AliMeeting会议数据集上获得当前最优性能。欢迎大家下载。开发者可以基于此模型进一步利用ModelScope的微调…...

刷题记录:牛客NC25078[USACO 2007 Ope S]City Horizon

传送门:牛客 题目描述: Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at the city horizon and observe the beautiful silhouettes formed by the rectangular buildings. The entire horizon is represented by a number line …...

【Java|golang】 1238. 循环码排列---格雷编码

给你两个整数 n 和 start。你的任务是返回任意 (0,1,2,…,2^n-1) 的排列 p&#xff0c;并且满足&#xff1a; p[0] start p[i] 和 p[i1] 的二进制表示形式只有一位不同 p[0] 和 p[2^n -1] 的二进制表示形式也只有一位不同 示例 1&#xff1a; 输入&#xff1a;n 2, start …...

Python自动化测试框架封装和调用

封装与调用函数与参数化前言 面实现了参数的关联&#xff0c;那种只是记流水账的完成功能&#xff0c;不便于维护&#xff0c;也没什么可读性&#xff0c;接下来这篇可以把每一个动作写成一个函数&#xff0c;这样更方便了。参数化的思维只需记住一点&#xff1a;不要写死 登录…...

线程的执行

承接上文CPU原理简介程序的执行是由控制器发信号推动整个程序一步一步向前走&#xff0c;将数据存储在寄存器&#xff0c;从程序计数器中获取指令&#xff0c;比如先把3放到寄存器&#xff0c;再把5放到寄存器&#xff0c;再做一个加法&#xff0c;加法就是一个指令&#xff0c…...

【视频】海康摄像头、NVR网络协议简介

1、软硬件整体架构 2、涉及的网络协议 3、协议简介 3.1 海康私有协议 设备发现SADP:进行设备的发现、激活、修改网络参数、忘记密码等; SDK:4200、系统平台的接入前端设备,协议不对外开放,但对外提供接口库; ISAPI:Intelligent Security API(智能安全API),基于HTTP传输…...

【Spring的事务传播行为有哪些呢?Spring事务的隔离级别?讲下嵌套事务?】

如果你想寻求一份与后端相关的开发工作&#xff0c;那么关于Spring事务相关的面试题你就不能说不会并且不能不知道&#xff1f; 人生如棋&#xff0c;我愿为卒&#xff0c;行动虽慢&#xff0c;可谁曾见我后退一步&#xff1f; 一.Spring中声明事务的方式 1.1 编程式事务 编程…...

其实一点不难学会这三步一定让你学会制作一个『3D建模』大屏

上次已经教过大家怎样制作一个简单的2D数据可视化大屏~那有一些朋友们就会说那些炫酷的3D可视化大屏是怎样制作的呢&#xff1f;这不就来了&#xff0c;今天就教大家怎样用山海鲸可视化软件制作一个带3D建模的可视化大屏&#xff0c;并且最重要的是无需会特别复杂的3D建模知识。…...

【C++】C++的内存模型之四大分区

程序的内存模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区&#xff1a;存放函数体的二进制代码&#xff0c;由操作系统进行管理的全局区&#xff1a;存放全局变量和静态变量以及常量栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数值&…...

Vue跨级通信(重点)

当不使用Vuex的前提下&#xff0c;子孙传递就得使用另外一种办法&#xff1a;provide 和 inject 总结&#xff1a;provide / inject 类似于消息的订阅和发布。- inject接收数据。- provide提供或发送数据&#xff0c;&#xff08;1&#xff09;provide&#xff08;name&#xf…...

支付系统中的设计模式07:责任链模式

最近公司业务的发展果然如老板当初所画(预)饼(言)的那样红(恍)红(恍)火(惚)火(惚),蒸蒸日上,每天的流水都在不断攀升到新的高度,有不少人都从公司开发的电商平台挣到了钱。 不过问题也接着来了——运营部门经过老板的同意,也学着产品经理提出了下面几项非常合理…...

期末综合考试

一、概率论1、全概率公式、贝叶斯公式应用2、期望、方差、协方差的定义以及性质证明(1) 期望(2) 方差(3) 协方差二、数理统计1、参数估计(1) 矩估计(2) 最大似然估计(3) 综合例题一、概率论 1、全概率公式、贝叶斯公式应用 记住标黄的两段&#xff0c;上考场直接套数据&#x…...

数据结构与算法之爬楼梯动态规划

一.题目(爬楼梯)假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f;注意&#xff1a;给定 n 是一个正整数。示例 1&#xff1a;输入&#xff1a; 2输出&#xff1a; 2解释&#xff1a; 有两种方法可以爬…...

CleanMyMac4.12最新Mac电脑系统垃圾清理神器

CleanMyMac是Mac一款神器&#xff0c;特别是清理已卸载软件残留垃圾文件信息库比较全面。 clearmymac以极其快速和时尚的方式为您提供及时的建议&#xff0c;组织&#xff0c;更新和保护您的Mac。完全支持macOS 11&#xff08;Big Sur&#xff09;操作系统&#xff1b;它以其简…...