Unity网络开发前置知识
一、网络开发必备知识点
1.线程和线程池
(1)回顾——线程
Unity支持多线程
- Unity中开启的
多线程不能使用主线程中的对象
- Unity中开启
多线程后一定要关闭
,因为它是在unity编辑器生成一个线程,除非关闭编辑器否则不会关闭线程。
1 | Thread t = new Thread(()=>{ |
(2)线程池
命名空间:System.threading
类名:ThreadPool
作用:避免频繁创建删除线程带来性能消耗,产生内存垃圾,减少GC垃圾回收的触发。
ThreadPool中有若干数量的线程,如果有任务需要处理时,会从线程池中获取一个空闲的线程来执行任务。
当任务执行完毕后不会销毁,而是被线程池回收以供后续任务使用。
当线程池数量达到设置的最大值,任务会排队,等待其他任务释放线程后再执行。
相当于一个专门装线程的缓存池
优点:节省开销,减少线程的创建,继而有效减少GC触发。
缺点:
不能控制
线程池中线程的执行顺序
,也不能获取池内线程
的取消/异常/完成
的通知
ThreadPool是一个静态类,里面提供了很多静态成员。
①获取可用的
工作线程数
和I/o线程数
(这个数为极限,能开的最大值)
1 | int num1;//工作线程数 |
②获取线程池工作线程的最大数目和I/O线程的最大数目
1 | ThreadPool.GetMaxThreads(out num1,out num2); |
③设置线程池中可用同时处于活动状态的,工作线程的最大数目和I/o线程的最大数目。
大于次数
的请求将保持排队状态
,直到线程池线程可用更改成功为true,失败反false
1 | ThreadPool.SetMaxThreads(20,20); |
④获取线程池中工作线程的最小数目和I/0线程的最小数目(默认数目)
1 | ThreadPool.GetMinThreads(out num1,out num2); |
⑤ 设置最小线程数
1 | ThreadPool.SetMinThreads(5,5); |
⑥将方法排入队列以便执行,当线程池中线程变得可用时执行。从池子中取一个线程执行函数
1 | ThreadPool.QueueUserWorkItem((obj)=>{ |
2.Task任务类
(1)认识Task
命名空间:System.Threading.Tasks。
类名:Task
它是基于线程池的基础上对线程进行的封装,拥有线程池优点的同时,解决了使用线程池不易控制的弊端
本质:
一个Task对象就是一个线程
(2)创建无返回值Task的三种方式
① 通过new一个Task对象传入委托函数并启动
1 | Task t1 = new Task(()=> |
② 通过Task中的Run静态方法传入委托函数
1 | Task t2 = Task.Run(() =>{ |
③ 通过Task.Factory中的StartNew静态方法传入委托函数
1 | Task.Factory.StartNew(()=>{ |
(3)创建一个有返回值的Task
① 通过new一个Task对象传入委托函数并启动(加泛型)
1 | Task<int> t1 = new Task<int>(()=> |
② 通过Task中的Run静态方法传入委托函数
1 | Task<string> t2 = Task.Run<string>(() => |
③ 通过Task.Factory中的StartNew静态方法传入委托函数
1 | Task<float> t3=Task.Factory.StartNew<float>(()=>{ |
获取返回值:Task实例化类.Result
1 | t1.Result |
注意:
Result获取结果时会
阻塞线程
即如果task没有执行完成,会等待task执行完成获取到Result。
然后再执行后边的代码,也就是说 执行到这句代码时,由于我们的Task是死循环
主线程直接卡死
所以我们调用Result时:
要保证task线程执行完。
(4)同步执行Task
以上都是多线程异步执行
Task同步进行需要调用Task中的
RunSynchronously方法。
注:需要使用new Task对象的方式,因为Run和StartNew在创建时就会启动异步。
不Start 而是 RunSynchronously
1 | Task t = new Task(()=>{ |
(5)Task中线程阻塞的方式
① Wait方法:等待任务执行完毕,再执行后面的内容
1 | Task t1 = new Task(()=>{ |

② WaitAny静态方法:传入任务中任意一个任务结束就继续执行。
1 | Task.WaitAny(t1,t2); |
③ WaitAll静态方法:任务列表中所有任务执行结束就继续执行
1 | Task.WaitAll(t1,t2); |
(6)Task延续
① WhenAll静态方法 + ContinueWith方法:
传入任
务全部完毕
后再执行某任务
1 | Task.WhenAll(t1,t2).ContinueWith((t)=>{ |
通过延续函数的参数(即前一个任务对象),可以访问以下关键信息:
属性/方法 | 说明 |
---|---|
t.Status |
任务状态(如 RanToCompletion , Faulted , Canceled 等) |
t.Result |
如果前一个任务是Task<TResult> ,获取其返回值(需确保任务成功完成) |
t.Exception |
获取任务抛出的异常(如果任务失败) |
t.IsCompleted |
任务是否已完成(无论成功、失败或取消) |
t.Wait() |
阻塞当前线程,直到任务完成(通常不推荐在延续任务中使用) |
1 | //第二种写法 |
②WhenAny静态方法+ContinueWith方法:传入任务只要
有一个执行完毕
后再执行某任务
1 | 同上 |
(7)取消Task执行
主要运用到死循环里面。
方法一:加bool变量
方法二:通过CancellationTokenSource对象取消标识源类 来控制.还可以延时取消
1 | CancellationTokenSource c= new CancellationTokenSource(); |
总结:
- Task是Thread的封装
- Task可有返回值,Thread没有返回值
- Task可用执行后续操作,比如执行完task还可以追加task,thread没有这个功能
- Task可用更方便取消任务,包括延迟取消、取消回调。Thread更单一
- Task具有线程池的优点,同时又克服了线程池的缺点。可以控制池中执行顺序。
3.async和await
(1)什么是同步和异步
同步和异步主要修饰方法
同步方法:
- 当方法被调用是,调用者
需要等待
该方法执行完才能继续执行异步方法:
- 当方法被调用时
立即返回
,并获取一个线程执行该方法内部的逻辑,调用者不用等该方法执行完毕
我们会把一些不需要立即获得结果且耗时的逻辑设置为异步执行。避免由复杂逻辑带来的线程阻塞。
(2)什么时候需要异步编程
- 需要处理的逻辑严重影响主线程执行的流畅性时,我们需要使用异步编程
- 比如:
- 复杂逻辑计算
- 网络下载、网络通讯
- 资源加载
(3)异步方法async和await
async和await
一般需要配合Task
进行使用- async用于
修饰函数、lambda表达式、匿名函数
await
用于在函数中和async
配对使用- 主要作用:是等待某个逻辑结束,此时逻辑会返回函数外部继续执行,直到等待的内容执行结束后,再继续执行异步函数内部逻辑
使用async修饰异步方法:
- 在异步方法中使用await关键字,
不使用则会以同步方式进行
。- 异步方法名建议
以Async结尾
- 异步方法的返回值
只能
是void、Task、Task<>- 异步方法中
不能声明使用ref和out关键字变量
使用await等待异步内容执行完毕(配合task使用)
遇到await关键字时:
- 异步方法被挂起
- 将控制器返回给调用者(主线程)
- 当await修饰内容异步执行结束后,继续通过调用者线程执行后面 的内容
1 | public async void TestAsync() |

注:Unity中
大部分异步方法
是不支持异步关键字
async和await的,我们只有在协同程序中进行使用,但是可以装插件让这些异步方法支持。
但是,当我们用到.Net库中提供的API时可以使用
二、网络开发必备理论
1.网络基本概念
网络的作用:
让设备之间可用互相通信
网络的概念:
- 网络是由
若干设备
和连接这些设备的链路
构成。- 各种设备 间接或直接通过介质相连
- 数据信息通过编码成
2进制数值
进行传输,以电脉冲的形式
- 1是通过一个正电压传输。
- 0是通过一个负电压传输。
(1)局域网


(2)以太网

说人话:局域网就是
一种设备连接规范,一种网络连接协议
(3)以太网 网络拓扑结构
用传输媒体把计算机等各种设备互相连接起来的
物理布局
。连接过程中构成的几何形状
。
- 各个拓扑结构
相互配合使用
。


(4)城域网
一个城市范围内建立的网络,通常覆盖一个城市

(5)广域网


(6)互联网




2.IP 端口 Mac地址
(1)IP地址
- 基本概念:
- 由IP协议提供的一种统一的地址格式,是设备在网络中的具体地址。
- 简单理解:
- 类似于在网络上的设备电话号码。
(2)IP地址的分类


(3)端口号
通过IP地址我们可以在网络上找到一台设备
但是我们想要和设备通信,本质上
是设运行在设备上的应用程序通信。
而一台设备可能运行多个应用设备。
端口号就是帮助我们区分和哪一个程序通信的。
基本概念:
- IP地址决定设备在网络中的地址
而端口是不同应用程序在该设备上的门牌号
一台设备上不同的应用程序想要通信,就必须对应一个唯一的端口号。

信息传输
的必须:IP地址+端口号

(4)Mac地址
物理设备(网卡)的唯一标识。



MAC地址就像身份证号,IP地址就好像你的住址。
MAC地址是物理层面上的通信基础,IP地址是逻辑层面上的通信基础。

3.客户端和服务端
(1)客户端


(2)服务端

(3)游戏开发中的客户端和服务端



4.数据通信模型
即数据在通信时是如何管理的
一般分为:
分散式、集中式、分布式
- 分散式

- 集中式

- 分布式


(1)C/S模型

(2)B/S模型

(3)P/P模型


5.OSI模型
(1)OSI模型是什么
- 简单来说:
- 就是
人为定义
的一个标准
- 它制定了设备之间互相连接、相互通信的标准
- 各公司按照这个标准设计的规则,就可以让不同设备利用互联网进行互联通信。
(2)OSI模型的规则

OSI模型把互联通信的过程分成了
七个层级

(3)OSI模型每层的职能

- 物理层
- 负责传送0和1的电信号,
将2进制数据利用电脉冲实现比特流传输
。- 主要功能:定义传输模式、定义传输速率等等。
- 数据链路层
- 网络层
- 传输层
- 应用层
- 表示层
- 会话层
总结


6.TCP/IP协议
(1)TCP/IP是什么
- 即
网络传输或通讯协议
- 就是一系列规则(协议)的
统称
。- 他
不仅仅指TCP和IP
两个协议,还包括FTP,SMTP,UDP等。
(2)TCP/IP协议的规则
(3)TCP/IP每层职能
对比:
![]()
7.TCP与UDP
(1)什么是TCP与UDP
- TCP:传输控制协议
- UDP:用户数据报协议
区别:
TCP UDP 连接方面 面向连接(比如:打电话要先拨号连接) 无连接。发数据前不需要建立连接 安全方面 无差错、不丢失、不重复、按序到达 不保证可靠,尽力交付 传输效率 相对较低 相对较高 连接对象 一对一 一对一,一对多,多对一,多对多
(2)TCP协议
三次握手(建立连接)
:
四次挥手(断开连接)
:
TCP协议有了这三次握手四次挥手,就可以做到传输数据可靠、不丢失、不重复、按顺序到达。