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

JavaEE 网络原理——TCP的工作机制(末篇 其余TCP特点)

文章目录

  • 一、滑动窗口
  • 二、流量控制
  • 三、拥堵控制
  • 四、延时应答
  • 五、捎带应答
  • 六、面向字节流
  • 七、异常情况
  • 八、总结

其余相关文章: JavaEE 网络原理——TCP的工作机制(中篇 三次握手和四次挥手)

本篇文章衔接的是前面两篇文章的内容,在这里继续解释 TCP 的内部原理。

一、滑动窗口

我们知道,可靠性和传输效率是相互矛盾的
对此,我们就需要在保证可靠性的基础上,来尽可能的提高传输效率。(尽量降低效率的折损)
在这里插入图片描述
如图所示:对于基本的确认应答的情况来讲,每次发送一个数据,都需要进行等待,再到 ack 到达后才会发送下一个。

因此,为了解决上述的问题,滑动窗口就此诞生。如图:
在这里插入图片描述
滑动窗口的本质是:不等待的批量发送一组数据,然后使用一份时间来等待着数组和多个 ACK。
窗口大小: 将不需要等待,就直接可以发送的数据的最大的量,称之为 “窗口大小”。

  • 问题1
    当批量发送窗口大小这些数据后,发送方就要等待 ack 了。
    呢么,问题来了,什么时候继续向下发送?等待什么时候结束?

不是说,等待到所有的 ack 到达,才能继续向下发送,而是到一个 ack ,就会继续向下发送下一条。(此处的等待的 ack 始终是 4 条)
这里简单举出一个例子:
假设本人当前是一个客服的工作人员,需要对用户的问题进行逐一的回答。(本人只能一次和 4 个用户进行沟通)
简单分析:
此处,这里的 4 就是窗口大小。
是将这里的 4 个客户都解决完毕后,才继续后面的 4 个客户吗? 很显然这里不是这样的!!!
而是在这 4 个客户中,只要有一个客户的问题解决后,就可以开启和下一个客户交流了。(始终是同时在和 4 个客户聊天)

具体情况如图:
在这里插入图片描述
如上图所示,本来等待 ack 是 1001 - 5000.
接下来,收到了 2001 这个 ack,此时说明 2001 之前的数据 (1001 - 2000) 已经被确认了。
此时就可以立即发送 5001 - 6000 的数据,此时意味着等待 ack 的范围就是 2001 - 6000。

  • 问题 2
    在滑动窗口的情况下,此时,出现丢包的情况该怎么办?

情况1:返回的 ack 丢失了。
在这里插入图片描述
其实,对于这样的情况,不需要去做任何的处理,问题不大。
关键需要理解的要点在于 确认序号 的含义。
这里的 “确认序号” 所表示的是该序号向前的所有数据都已经确认送达了。
也就是说,这里的 1001 返回的 ack 虽然丢失,但是后面的 2001 处返回的 ack 实际上涵盖了前面从 1 - 1001 处的 ack 信息。

情况2:数据丢失
在这里插入图片描述
如上图所示,1001 - 2000 在传输时出现丢包情况。在接下来的 2001 - 3000 到达主机 B 之后,由 B 给 A 返回的 ACK 确认序号仍然是 1001. (此时和你发送过来的这个数据号是什么,关系已经不大了。)

这里的意思就是在索要 1001 开头的数据。

在这里,对此处的丢包重传方式起了一个新的名字,叫做 “快速重传”(重传操作只是重传了丢失的数据)。
这里的重传机制可以视为是超时重传机制在滑动窗口下的变形。
注:如果此处的传输数据比较密集,就按照滑动窗口的方式来传输。
如果此处的传输数据比较稀疏,就不在按照滑动窗口的方式了,此时就还按照之前的超时重传的形式来处理丢包。

快速重传中的问题

  1. 有关补发数据是否会出现数据顺序混乱的情况。
    解释: 这个问题并不复杂,TCP 中有一个接收缓冲区,在缓冲区中会对数据按照序号进行重新排队。
  2. 以上面图片中的情况为例,假设此时在 2001 - 7001 之间有丢失了一组,此时的情况该是怎样?
    解释: 这里其实也不难理解,当 主机 B 接受到 1001 - 2000 后,就会再次按顺序向后索取缺少的其他范围的数据。

二、流量控制

流量控制作用: 这是一种干预发送窗口大小的机制。
在上面的一个要点中,我向大家讲解了 滑动窗口。对于滑动窗口,窗口越大,传输的效率就会越高。(也就是说,在一份时间中,等待的 ACK 就越多)。
但是,窗口的大小也不能无限大!!!

可能出现的问题如下:

  1. 完全不等待 ack ,在可靠性能否保障画上问号。
  2. 窗口太大,也会消耗大量的系统资源。
  3. 发送的速度太快,接受方处理不过来,发了也没什么用。。。

其实,综上所述,接受方的处理能力,就是一个很重要的约束依据。发送方的速度,不能超出接受方的处理能力!

流量控制,要做的工作就是这个。根据接受方的处理能力,协调发送方的发送速率。

所以,如何衡量接收方的处理能力 就是这里的关键所在

解释: 如何衡量接受方的处理能力

这里有一个最简单直接的方法,直接观察接收方的缓冲区剩余大小。
在这里插入图片描述
如上图所示,每次 A 给 B 发送个数据。
B 就需要计算下一个水池中的剩余空间,然后将这个值通过 ack 报文返回给 A
A 此时就根据这个值来决定接下来发送的速率是多少。(窗口大小是多少)

在这里插入图片描述
通过上图所示,窗口大小就指的是 16 位窗口大小。
但是,这里是否就意味着,窗口大小最大是 64kb?答案显然不是这样的!TCP 为了让窗口更大,在选项部分,引入了窗口拓展因子

解释: 窗口拓展因子如何作用。

假设: 此时,窗口大小已经是 64kb。在拓展因子中写入 2.
这里的意思就是让 64kb << 2 ——> 256 kb

所以,通过上面的分析我们可以知道,接受缓冲区一直是在动态变化的,所以,对应的每次返回的 ack 携带的窗口大小也在变化。对此,发送方也是在不断的动态调整的!!!

特殊情况: 当窗口的大小为 0 时。
此时,发送方就会暂停发送,在暂停发送的等待过程中,会给 B 定期发送窗口探测报文。这个报文不会携带任何的具体业务数据,只是为了触发 ack 查询窗口大小。

三、拥堵控制

这里的拥堵控制,与前面向大家解释的流量控制共同决定发送方的窗口大小的多少。

这里描述的 “发送发窗口大小” 是通过 接收方 的 ack 报文中的 窗口大小字段。是从 接收方 告诉给 发送方 的!

流量控制: 考虑的是接收方的处理能力。
拥塞控制: 考虑的是传输过程中,中间节点的处理能力。

在这里插入图片描述
形如上图所示,对于两台主机 A,B 两者之间传递数据,是需要在中间经过多台设备的

对于接受方的处理能力,是比较好量化衡量的。但是 中间节点 ,不好衡量。

因此,为了解决这个问题,设计 TCP 的大佬们想出了一个非常天才的方法。
既然不好直接量化,呢么就可以通过 “实验” 的方式来测试出一个合适的值。

解释: 如何通过测试获取合适的值。

在这里插入图片描述
如上图所示,这里的 “拥塞窗口” 表述的是,不断尝试要以多大的窗口进行发送。
初始阶段: 由于初始窗口比较小(从1开始),此时每一轮的不丢包,都会使窗口大小扩大一倍(指数增长)。
中间阶段: 当增长率到达阈值时,此时的指数增长就会变成线性增长。(注意,这里增长的前提是不丢包)
调整阶段: 当传输过程中一但产生丢包,呢么说明此时,发送的速率已经接近网络的极限。此时,一下子就会把窗口大小缩成很小的值。(并且重复前面的指数增长和线性增长的过程)
通过上面的分析,可以的出一个结论
拥塞窗口不是一个固定的数值,而是一直动态变化的。随着时间的推移,逐渐达到一个平衡的过程。

上面的动态处理,即可以把问题解决,同时也可以随着网络情况的变化而变化

四、延时应答

延时应答,在这里也是一个为了提高效率的机制
这个机制,也就是对滑动窗口进行补充。

滑动窗口的关键,就是让窗口的大小大一点,传输的速度就快一点。
因此,需要做的就是,在接收方能够处理的了的前提下,尽可能将窗口的大小放大。

延时应答,就是在接受数据后,不是立即返回 ACK 而是稍等一会在返回。
在这个等待的时间中,接受方的应用程序,就可以将缓冲区的数据进行一波消费,此时剩余的空间不就变大了一点。。。
如图:
在这里插入图片描述
这里表现出的延时应答方式,就是在滑动窗口下。ACK 不在对每一条数据进行返回,比如隔一个返回一次。

五、捎带应答

捎带应答也是提高效率的一种方式。
捎带应答的引入,是在延时应答的基础之上的。

我们已经知道,服务器客户端程序,最典型的模型就是 “一问一答”。
如图:
在这里插入图片描述
从上图可以看出,这两个信息根本就是不同时机产生,不同时机发送。

捎带应答,就是在这两条信息中进行动作的。
在之前的延时应答机制中,因为要等待缓冲区中的数据消费。所以,就会导致在等待 ACK 的过程中,B 就要向 A 发送业务数据了。呢么此时,就可以让这个业务数据 捎带着 ACK 一并发送过去 即可。
如图:
在这里插入图片描述

注意:
这里要说的是,“合并发送” 这个事情是成立的,并不是说有了 “捎带应答” 就一定会合并
而 “延时应答” 则是提高了合并的概率。

六、面向字节流

当数据面向字节流时,此时,在这里就引入了一个比较麻烦的事—— 粘包问题

在这里插入图片描述
在前面的说明中,我们已经知道了一个名词 “接收缓冲区”
在上图中的多次交互中,其实所有的交互信息都会被存入到 接受缓冲区 中,这里的多个数据都会被放到一起。
呢么,问题来了
此时应用程序在 read 读取的时候,读取到哪里才算是一个完整的应用层数据报呢?

在这里插入图片描述
如上图所示,我们大家都知道,糯米团子的粘度是很大的。想要单独拿出来一个,很容易就会出现粘连的情况。

TCP 是字节流的。
一次读取一个字节,读取 N 个字节,都是可以的。
在这样的情况下,一次读取的是半个数据报,或整个数据报,或多个数据报的情况都是存在的!

解释: 描述 “粘包” 具体情况。

这里是引用
以上图的情况为例,应用程序调用 read
如果 read 的是 7 个字节,此时正好读出的是 aaaaaaa ,这就是一个完整的数据报。
如果 read 的是 8 个字节,此时读到的就是 aaaaaaab ,读到的就是 “一个半” 数据。
如果 read 的是 6 个字节,此时读到的是 aaaaaa ,读到的就是 半个数据报。

综上所述,粘包问题的影响还是比较大的。
但是,还有一个更令人悲伤的故事。。。
在 TCP 层次,没有在 socket api 中告诉我们应该读取几个字节。具体要怎么读,完全是程序员自己负责。

我们肯定是想读到的是一个完整的一个数据报。
解决问题的方法其实也非常简单,只需要在应用层中约定好应用层协议即可。
尤其是要明确应用层数据报之间的边界就好。

约定的条件有下面的两条
1.约定好分隔符。
2.约定好每个包的长度。

七、异常情况

对于异常情况,直接说明就是在传输过程中出现了不可抗力

对于不可抗力大概有下面几点情况:

1 进程崩溃
2.主机关机(按照正常流程关机)
3.主机断电
4.网线断开

这里我们将上述情况分为下面两部分:

  • 情况 1 和 2
    针对这两种情况,直接对应的是进程没了
    (1)在 进程崩溃 情况下,对应的 PCB 也就没了,对应的文件描述符表也就释放了。相当于 socket.close()。 此时内核会继续完成四次挥手。其实仍然是一个正常断开的流程。
    (2)对于 主机关机 主机关机要先杀进程,然后才会正常关机。(在杀死进程的过程中,也和上面一样会触发四次挥手)。

  • 情况 3 和 4
    针对这两个情况显然是来不及挥手了
    (3)对于 主机掉电 在这里可以分为两类情况。
    假设 接受方 掉电
    发送方 仍然在继续发送数据,发送完需要等待 ack ,但是 ack 始终等不到。。。
    超时重传在怎么重传,也收不到 ack。。。
    在重传几次后,仍然没有应答,此时尝试尝试重置 TCP 的连接。但是很显然这个重置也会失败。
    最终只能放弃连接(单方面放弃)。
    如果是 发送方 掉电
    接受方 发现,没数据了。此时接受方还不知道发送方是一个什么情况。(此时,接收方能做的事就只有一件,等待!)
    在等待一段时间后,接收方 会周期性的向 发送方 发送一个消息。来确认对方是否还在正常工作。

接受方周期性的发送信息,在这里有一个更加形象的名字 心跳包
1.心跳,是一个周期性的。
2.如果心跳无了,呢么就说明挂了
在这里也就是通过心跳包来确认通信双方是否处在一个正常的工作状态中。。

八、总结

到此,本人使用了长达三篇文章对 TCP 中最重要的十个特性进行了描述。但是这里的学习仍然任重道远。还需要反复的思考琢磨来达到更清晰的理解。

码子不易,您小小的点赞是对我最大的鼓励!!!

相关文章:

JavaEE 网络原理——TCP的工作机制(末篇 其余TCP特点)

文章目录 一、滑动窗口二、流量控制三、拥堵控制四、延时应答五、捎带应答六、面向字节流七、异常情况八、总结 其余相关文章&#xff1a; JavaEE 网络原理——TCP的工作机制(中篇 三次握手和四次挥手) 本篇文章衔接的是前面两篇文章的内容&#xff0c;在这里继续解释 TCP 的内…...

【软件测试】了解JUnit单元测试框架常用注解

目录 1、认识JUnit 2、Junit中常见的注解 1、Test 2、Disabled 3、BeforeAll和AfterAll 4、BeforeEach和AfterEach 5、 ParameterizedTest&#xff1a;参数化 6、order 3、断言 1、断言相等【Assertions.assertEquals(预期&#xff0c;比较值)】&#xff1b;相等测试通…...

【广州华锐互动】三维全景3D消防科普展馆

在我们的日常生活中&#xff0c;火灾安全是一个不容忽视的重要问题。然而&#xff0c;由于缺乏对火灾的了解和应对技巧&#xff0c;许多人在面对火灾时往往感到无助和恐慌。为了解决这个问题&#xff0c;广州华锐互动开发了三维全景3D消防科普展馆&#xff0c;它是一个以虚拟现…...

某大型车企:加强汽车应用安全防护,开创智能网联汽车新篇章

​某车企是安徽省最大的整车制造企业&#xff0c;致力于为全球消费者带来高品质汽车产品和服务体验&#xff0c;是国内最早突破百万销量的汽车自主品牌。该车企利用数字技术推动供应链网络的新型互动&#xff0c;加快数字化转型&#xff0c;持续进行场景创新、生态创新&#xf…...

LLVM学习笔记(50)

4.1.4. DAG合并与合法化 来自SelectionDAGBuilder的SelectionDAG输出还不能进行指令选择&#xff0c;必须通过额外的转换——显示在上图。在指令选择前应用的遍序列如下&#xff1a; 匹配一组节点&#xff0c;在有利时使用更简单的构造来替换它们&#xff0c;DAG合并遍优化Se…...

rpc入门笔记0x01

syntax "proto3"; // 这是个proto3的文件message HelloRequest{ // 创建数据对象string name 1; // name表示名称&#xff0c;编号是1 }生成python文件 安装grpcio和grpcio-tools库 pip install grpcio #安装grpc pip install grpcio-tools #安装grpc tools生成…...

web - Tomcat服务器

文章目录 目录 文章目录 前言 一 . CS和BS的异同 二 . 什么是Tomcat 二 . Tomcat安装 四 . Tomcat目录结构 bin目录: 用于存放二进制的可执行文件 config目录 server.xml&#xff1a;配置整个服务器信息。例如修改端口号。默认HTTP请求的端口号是&#xff1a;8080 lib目录 log…...

后端接口返回常见的状态码

2开头 &#xff08;请求成功&#xff09;表示成功处理了请求的状态代码 200 &#xff08;成功&#xff09; 服务器已成功处理了请求。 通常&#xff0c;这表示服务器提供了请求的网页。 201 &#xff08;已创建&#xff09; 请求成功并且服务器创建了新的资源。 202 &#xf…...

50.MongoDB快速入门实战

MongoDB概念 MongoDB是一个文档数据库&#xff08;以 JSON 为数据模型&#xff09;&#xff0c;由C语言编写&#xff0c;旨在为WEB应用提供可扩展的高性能数据存储解决方案。 原则上 Oracle 和 MySQL 能做的事情&#xff0c;MongoDB 都能做&#xff08;包括 ACID 事务&#x…...

一款功能强大的音乐曲谱软件Guitar Pro 8 .1.1for Mac 中文破解版

Guitar Pro 8 .1.1for Mac 中文破解版是一款功能强大的音乐曲谱软件&#xff0c;非常适合学习如何玩&#xff0c;改进技巧&#xff0c;重现喜爱的歌曲或陪伴自己。可以帮助我们进行吉他的学习、绘谱与创作&#xff0c;它包含了几乎所有的吉他现有指法及音色&#xff0c;在做弹拨…...

图论基础和表示

一、概念及其介绍 图论(Graph Theory)是离散数学的一个分支&#xff0c;是一门研究图(Graph)的学问。 图是用来对对象之间的成对关系建模的数学结构&#xff0c;由"节点"或"顶点"(Vertex&#xff09;以及连接这些顶点的"边"&#xff08;Edge&a…...

STM32 音频ADC转wav格式

STM32 音频ADC DAC测试方法_stm32 adc 音频-CSDN博客 STM32--vs1053 WAV录音实现&#xff08;保存在SD卡&#xff09;_vs1053 多字节读取-CSDN博客 单片机内部AD实现录音wav文件_adc语音信号采样_天外飞仙CUG的博客-CSDN博客 PCM编码格式_pcm格式-CSDN博客 用ADC编码PCM数据…...

面试中经常问道的问题二

深入理解前端跨域方法和原理 前言 受浏览器同源策略的限制&#xff0c;本域的js不能操作其他域的页面对象&#xff08;比如DOM&#xff09;。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。所以我们要通过一些方法使本域的js能够操作其他域的页面对象或者使…...

SQL UPDATE 语句(更新表中的记录)

SQL UPDATE 语句 UPDATE 语句用于更新表中已存在的记录。 还可以使用AND或OR运算符组合多个条件。 SQL UPDATE 语法 具有WHERE子句的UPDATE查询的基本语法如下所示&#xff1a; UPDATE table_name SET column1 value1, column2 value2, ... WHERE conditi…...

js节流和防抖

节流&#xff08;throttle&#xff09;和防抖&#xff08;debounce&#xff09;是为了解决函数频繁触发而引发性能问题的两种优化方法。 节流&#xff1a; 指定一个时间间隔&#xff0c;在时间间隔内只执行一次函数&#xff0c;即在一段时间内&#xff0c;多次触发函数只执行一…...

权限系统设计(转载)

1 为什么需要权限管理 2 权限模型 2.1 权限设计 2.2 为什么需要角色 2.3 权限模型的演进 2.4 用户划分 2.5 理想的RBAC模型 3 权限系统表设计 3.1 标准RBAC模型表设计 3.2 理想RBAC模型表设计 4 结语 1 为什么需要权限管理 日常工作中权限的问题时时刻刻伴随着我们&a…...

【机器学习合集】标准化与池化合集 ->(个人学习记录笔记)

文章目录 标准化与池化1. 标准化/归一化1.1 归一化归一化的作用 1.2 标准化批标准化方法 Batch Normailzation标准化方法的对比自动学习标准化方法 2. 池化2.1 池化的作用2.2 常见的池化方法2.3 池化方法的差异2.4 池化的必要性 标准化与池化 1. 标准化/归一化 1.1 归一化 归…...

Dockerfile文件自动化生成R4L镜像

Dockerfile文件自动化生成R4L镜像的步骤 1、安装Docker&#xff1a;2、使用Dockerfile一键生成镜像&#xff1a;3、查看生成的Docker镜像&#xff1a;4、删除Docker镜像&#xff1a;5、生成Docker容器&#xff1a;6、查看容器7、删除容器 1、安装Docker&#xff1a; curl -fsS…...

基于SSM的居家养老系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…...

[C#基础训练]FoodRobot食品管理部分代码-2

参考代码&#xff1a; using System; using System.Collections.Generic;namespace FoodRobotDemo {public class FoodInfo{ public string Name { get; set; } public int Id { get; set; } public int Count { get; set; }}public class FoodRobot{private …...

docker部署rabbitmq的坑

背景 今天用docker部署rabbitmq&#xff0c;启动都一起正常&#xff0c;但是当访问15672端口时&#xff0c;不能加载出页面。 排查 1.防火墙是否开启 ufw status2.ip是否能ping通 ping 192.168.x.x3.检查docker日志 docker psdocker logs -f 容器id4.进入容器&#xff0c…...

【python VS vba(系列2)】 python和vba读写EXCEL文件的方式比较 (建设ing)

目录 1 用VBA读写EXCEL文件 1.1 用VBA读写&#xff0c;本工作簿workbook里的特定sheet的特定内容 1.1.1 EXCEL表内内容访问 1.1.2 注意点 1.1.3 代码 1.2 用VBA读写本工作簿workbook里的所有sheet的内容 1.2.1 麻烦之处 1.2.2 方法&#xff0c;如何指定EXCEL里的内容…...

小程序 swiper滑动 层叠滑动效果

整个红色区域为可滑动区域&#xff0c;数字1区域为展示区域&#xff0c;数字2为下一个展示模块 <scroll-view class"h_scroll_horizontal" enhanced"ture" bind:touchend"touchEnd" bind:touchstart"touchStart"><view clas…...

【20年VIO梳理】

19-20年VIO 梳理 1. 开源代码介绍&#xff1a; DSM2. FMD Stereo SLAM&#xff1a;融合MVG和直接方法&#xff0c;实现准确&#xff0c;快速的双目SLAM3. 基于VINS-Mono开发的SPVIS4. 改进&#xff1a;一种基于光流的动态环境移动机器人定位方案5. PVIO:基于先验平面约束的高效…...

Java Object类详解

Object 是 java 类库中的一个特殊类&#xff0c;也是所有类的父类。也就是说&#xff0c;Java 允许把任何类型的对象赋给 Object 类型的变量。当一个类被定义后&#xff0c;如果没有指定继承的父类&#xff0c;那么默认父类就是 Object 类。因此&#xff0c;以下两个类表示的含…...

Unity 中忽略图片透明度的 Image 组件的修改版本

只需将此组件添加到画布中的空对象即可。请注意&#xff0c;仅支持简单 图像类型。 using System.Collections.Generic; using UnityEngine; using UnityEngine.Sprites; using UnityEngine.UI; #if UNITY_2017_4 || UNITY_2018_2_OR_NEWER using UnityEngine.U2D; #endif#if U…...

hibernate源码(1)--- schema创建

sessionFactory 配置项&#xff1a; hibernate的核心是sessionFactory&#xff0c;那我们看看如何构建session Factory。 参考官网&#xff1a; plugins {id("java") } group "com.atai.hibernatespy" version "1.0-SNAPSHOT" repositories…...

数学与经济管理

数学与经济管理&#xff08;2-4分&#xff09; 章节概述 最小生成树问题 答案&#xff1a;23 讲解地址&#xff1a;74-最小生成树问题_哔哩哔哩_bilibili 最短路径问题 答案&#xff1a;81 讲解地址&#xff1a;75-最短路径问题_哔哩哔哩_bilibili 网络与最大流量问题 真题 讲解…...

自动化测试系列 —— UI自动化测试

UI 测试是一种测试类型&#xff0c;也称为用户界面测试&#xff0c;通过该测试&#xff0c;我们检查应用程序的界面是否工作正常或是否存在任何妨碍用户行为且不符合书面规格的 BUG。了解用户将如何在用户和网站之间进行交互以执行 UI 测试至关重要&#xff0c;通过执行 UI 测试…...

眨个眼就学会了PixiJS

本文简介 带尬猴&#xff0c;我是德育处主任 当今的Web开发中&#xff0c;图形和动画已经成为了吸引用户注意力的重要手段之一。而 Pixi.js 作为一款高效、易用的2D渲染引擎&#xff0c;已经成为了许多开发者的首选&#xff08;我吹的&#xff09;。本文将为工友们介绍PixiJS的…...