当前课程知识点:游戏程序设计 > 第十章 《网络同步技术》 > 10.4 常用同步方案 3 > 10.4 常用同步方案 3
然后在前面
我们就针对一致性
这个问题上
介绍了帧同步和状态同步是怎么做的
然后我们再看看
再及时性这个问题上
这两种方案
这两种同步方案
它们是有哪些共同的措施
来去解决这个问题
总的来说
其实及时性问题
它主要会划分为三块
三类
一个是网络方案的选择
另外一个是对时方案的选择
以及它去为了去掩盖一些延迟
要去做一些欲表现的一些方案
我们现在先来看一下
网络方案里面我们会有哪些具体的选择
首先
第一个选择就是网络协议的选择
我们选择TCP还是UDP呢
我们来看这个表格
无论网络环境良好
还是有丢包
还是有抖动
可看到UDP 的平均延迟
是都要小于TCP的
总体来看在UDP得到
可靠性得到保证的情况下
它对于弱网络的表现是要好于TCP的
因此在弱网络下
我们一般选择用可靠UDP
来作为一个通讯协议
接下来我们来介绍可靠UDP的实现原点
首先我们需要知道几个概念
第一个就是RTT
它是指发送端发送一个数据包
直到收到接收端的应答
中间所消耗的时间
我们来看一下这个图
A作为发送方
发送M1给了B
B收到M1之后
给A发送一个确认应答包
那么这中间的时间就是一个RTT
第二个概念是RTO
是指存传超时时间
也就是指发送端发送一个数据包
然后呢
等待一定时间之后
如果没有收到接收端的确定
会重新发送之前的数据包
我们来看这个图A发送M1给B
那么因为各种原因M1被丢掉了
B没有收到
也就是说B没办法给A发送确认
那么这个时候A就会
设定一个超时时间
等到超出之后会重发M1
那么这个超时时间就是RTO
也就是超时重传的一个超时时间
最后一个概念是
最小丢包延时
我们来看这个图吧
A发送了M1
给B
由于A M1被丢掉了
B没有收到
那么A会等待RTO之后会重发M1
因为是最小丢包延时
那么就假设它只会丢一次包
那么当A重发M1的时候
B收到了这个包
那么从A一开始发送M1
到B最终收到M1中间的时间
就是所谓的最小丢包延时
接下来我们来介绍两种实现可靠UDP的原理
第一种是基于ARQ的原理
什么是ARQ呢
我们来看一下
下面这个图
A作为发送者发送M1给B不幸丢包了
这个时候A
就会等到超时之后去重传M1
那么这个过程就被称之为
自动重传请求
那么的自动重传请求又根据什么时候发生M2
以及发生M2之后怎样发生M3
而分为三种具体的实现方式
我们下面来详细的介绍这三种实现方式
一个是等待式一个是后退N步
还有一个呢
就是选择重发
什么是等待式呢
我们来看一下下面这个图
A发送了M1给B
那么不幸丢包了
这个时候呢
A就会进行超时重传M1
那么什么时候发送M2呢
我们来看这个图
它是需要等到M1
被B确定之后才会发送M2
那么中间就会有个问题
大家看
我们把A和B中间这个空白的通道
相当于是网络通信的信道
我们来看一下这个信道
它的包其实非常少
而现在我们网络的信道其实非常宽
已经是有百兆的千兆的这种带宽了
如果在这种带宽下面
我们这么系数的包
其实是对这个带宽的一种浪费对吧
所以呢
我们针对这种情况
就会有一些进一步的优化
那么是怎么样优化了呢
我们来看一下
下一种方式
什么是后退N步这种方式呢
我们来看一下下面这个图
这个图看起来有点复杂
但其实也很简单
A发送了M1给B
那么这个时候呢
A并不会等待B对M1的确认
A会立即发送M2
同时一样的会立即发送M3
然后发送M4
发送M5
那么这个时候由于M3丢包了
丢包之后的B没办法去确认M3
那么A就会启动对M3的超时重传
那么
A在重传M3的时候呢
又会把M4和M5重传一次
但为什么会出现这种情况呢
是因为在这种方式下B
一旦发现M3没有收到
那么后面的包都会被丢弃掉
由于后面的包被丢弃了
于是A在重传M3之后
需要将M3后面的包再重传一次
那么这样会带来一个什么问题呢
会带来对网络通信信道的一个浪费
这个浪费和上一课的浪费是不样的
上一个方式浪费是
通道过于空旷
而这种方式浪费是通道过于拥挤
这两种其实都是浪费
我们为了尽可能去利用好这个网络通信的通道
那么我们是需要对这种的方式
进一步优化的
那么怎么优化呢
我们来看看下面那一种方式
最后一种方式就是选择重传
那么这种方式
其实是对后退N步的一个优化
也就是说
它把M4M5缓存起来了
因为被缓存起来了
所以说在超时重传的时候
不需要再传送
M4M5了
可以从M3直接跳到M6M7
下面我们来介绍第二种
实现可靠UDP的原理
也就是基于FEC的原理
什么是FEC呢
我们来看一下这个图
A给B发包
首先A
发送了第一个包
叫做F1
那么A
这个时候并不会等待B的回报确认
也不会去等待这个包的超时
而是间隔一个固定的时间
FT之后
去发F2
那么在发F2的时候
因为F1还没有被确认
也没有超时
于是就会将F1附带着F2一起发送过去
一样的
它会接着去间隔的FT
这个时间之后去发F3
由于发F3的时候
F1和F2都没有被确认
那么这个时候就会将F1
和F2
附带在F3后面一起发送过去
那么这个时候B
收到了F2
那么就会给A发送确认
那么
当A收了F2的确认的时候
它会隐含确认F1
那么接下来
在A发送F4的时候呢
就不会带上F1和F2了
只会带上还没有被确认的F3
那么这种方式我们把它称之为
FEC的原理
也就是所谓的前项
冗余纠错这样一个原理
那么它的一个特点是什么的
它特点就是它的最小丢包延时
是要小于ARQ的最小丢包延时的
那么
我们到底是选择ARQ还是FEC呢
其实这两种方式它们各有各自的优缺点
我们需要根据实际的情况
来选择使用哪种原理来实现可靠UDP
对于ARQ来讲它的优点是
它的算法应用场合比较广泛
有大量现成的实现方案
而缺点就是
它的最小丢包延时较高
一般是等于
一点七到两倍的RTT
而FEC呢
它优点是
最小丢包延时是比较低的
一般来讲是低于一点五倍RTT的
但是它的缺点就是算法稍微比较复杂
它局限于帧同步这种特殊的应用场合
并且呢
一般来讲没有现成的实现方案
需要你自己去实现
我们可以根据我们
项目的实际情况来决定
我们需要使用哪种方式来实现可靠UDP
如果我们使用帧同步项目的话
那我们一般来讲
我们用FEC是比较好的
但是如果是非帧同步项目
我们可以使用了ARQ来实现
在我们选择好协议之后
我们接下来就需要对网络进行一个优化
那么怎么优化呢
首先
第一步我们需要进行UDP分组的优化
大家有没有听过UDP分组的概念呢
其实就是将一个UDP的大包
分成几个UDP小包进行发送
那么为什么我们需要进行UDP 的分组呢
为了能够比较好地理解UDP 的分组优化
我们首先需要知道什么是IP分片重组
我们来看一下这个图
我们的网络传输链路
其实非常复杂
我们可能以为很简单
以为直接从手机连到服务器了
但事实上
它中间要经过很多个网络设备
有线网络设备
建设的年代比较古老
那么它们的MTU都各不相同
当一个UDP 大包
在网络链路上进行传输的时候
如果说这个链路的MTU
小于这个UDP的包的大小
那么系统就会将这个UDP大包
拆分成一个个IP包进行发送
这就是所谓的IP的分片
而接收方收到这些IP包之后
会把它们去组合成
这个有UDP 大包就是重组
这个过程呢
可能会造成丢包
那么任何一个IP包被丢了
那么系统就会认为
整个UDP包被丢了
也就是说
如果这个UDP 包越大
而,TU越小
那么这个时候IP分片就越多
IP分片越多
那么就会造成
这个UDP 包的丢包概率越高
它们为了避免
因为IP分片
丢包造成的整体UDP 包丢包概率
我们一般来讲会
人为的将UDP 大包变成小包进行发送
所以我们需要尽可能避免
UDP包大小
超过链路层最小MTU
这个最小MTU
尤其是一个经验值
因为网络中的设备
千变万化各种各样
那么目前来讲
这个经验值是470个字节
接下来我们来介绍一下对丢包的优化
丢包可以分为两种
一种是相关性丢包
一种是随机性丢包
接下来呢
我们来分别对于这两种丢包规律来进行优化
首先
我们来看相关线路的
相间线路丢包呢
我们来看一下这个图
红色代表丢包
从图中我们可以看出
它要么不丢
要么就会连续丢好几个
这种丢包的原因一般有以下几种
一个就是整个通讯电路拥塞了包塞多了
那么第二个就是路由器的负载过高
那么还有就是
无线信号衰减
就是没有信号了
再就是基站切换了
或者说场景切换了
比如说进出电梯等等
那么这种丢包它有个特点就是
它是有原因的
而这种丢包我们程序员一般来讲是无能为力的
我们想优化它
只能够采取社会工程学
比如说我们和运营商进行合作
或者说我们可以去一个比较好的地方
比如说我们在信号比较强的地方进行游戏
接下来我们来看随机性丢包
什么是随机性丢包呢
我们来看这个图
红色代表丢包
它是没有规律的随机的分布的
它的原因是什么的
就是@
就像这个世界上没有绝对的黑
也没有绝对的白一样
这个世界上没有绝对的不丢包
那么它就是会丢包
它的特点就是
没有规律随机出现
根据我们的实际的数据统计
我们目前有90%左右的包
丢包都属于这一种
随着网络环境的改善
这个比例会越来越高
越来越高
那么接下来我们就需要问了
连续K次丢包的概率有多少
为了优化随机丢包
我们需要引入一个模型
叫做@模型
基于这个模型
我们可以计算出一个公式
用来计算连续K个丢包的概率
那么这个公式推导过程
我们可以在网上找到相关的资料
那么通过这个公式
我们可以得出一个结论
就是连续K次丢包的概率
其实是非常非常低的
随着K 的增加
这个丢包的概率会急速趋向于零
那我们怎么样利用这样一个公式
对随机丢包进行优化呢
其实很简单
就是对于同一个包
我们连发两次即可
如果两次不够
我们就发三次
直到我们将MTU填满
-1. 1什么是游戏(上)
--选择题
-1.2 什么是游戏(下)
--选择题
-1.3 游戏是如何开发出来的
-1.4 游戏引擎(上)
-1.5 游戏引擎(下)
--单选题
-1.6 如何成为一个游戏开发者
--多选题
-2.1 什么是游戏服务器
--单选题
-2.2 游戏服务器的和分类发展
--单选题
-2.3 核心技术和实现难点
--单选题
-2.4 设计原理与方法论
--单选题
-3.1 三维坐标系统
--多选题
-3.2 向量与运算
--单选题
-3.3 矩阵与线性变换
--双选题
-3.4 四元数
--3.4 四元数
--多选题
-4.1 游戏循环概述(上)
--多选题
-4.2 游戏循环概述(下)
--单选题
-4.3 《无尽之路》的实现
--单选题
-4.4 支撑游戏的功能
--选择题
-4.5 支撑游戏的机制与系统
--多选题
-5.1 基本介绍
--5.1 基本介绍
--单选题
-5.2 随机数生成器
--单选题
-5.3 随机数分布与应用
--单选题
-6.1 什么是游戏玩法开发
--单选题
-6.2 建立愿景 Vision
--单选题
-6.3 划定边界 Scope
-6.4 迭代 Iteration
--单选题
-6.5 迭代 Iteration+抛光Polish
--单选题
-7.1实时图形渲染管道 宏观渲染系统
--单选题
-7.2实时图形渲染管道 应用阶段
--单选题
-7.3实时图形渲染管道 几何阶段
--单选题
-7.4实时图形渲染管道 光栅化阶段
--单选题
-7.5实时图形渲染管道 总结 参考
-8.1 物理回顾1
--单选题
-8.2 物理回顾2
--单选题
-8.3 材质 1
--8.3 材质 1
-8.4 材质 2
--8.4 材质 2
-8.5 材质3
--8.5 材质3
-8.6局部光照
--8.6局部光照
--单选题
-8.7 全局光照
--8.7 全局光照
--单选题
-9.1 动画介绍
--9.1 动画介绍
--多选题
-9.2 游戏动画介绍
-9.3 动画技术类型
--多选题
-9.4 骨骼蒙皮动画
--多选题
-9.5 动画流水线
--多选题
-9.6 动画前沿趋势
--多选题
-10.1 .基本概念
--多选题
-10.2 设计目标
--多选题
-10.3 传输数据分析
--多选题
-10.4 常用同步方案 1
-10.4 常用同步方案 2
-10.4 常用同步方案 3
-10.4 常用同步方案 4
--多选题
-10.5 方案对比
--多选题
-11.1 基本图元
--单选题
-11.2 图元距离(上)
--单选题
-11.2 图元距离(下)
--单选题
-11.3 图元相交测试+ 其他几何方法
--单选题
-12.1 著名物理引擎介绍
--单选题
-12.2 物理引擎原理(上)
--单选题
-12.3 物理引擎原理(下)
--单选题
-12.4 游戏中的物理体
--单选题
-12.5 物理引擎使用入门
--单选题
-13.1开发语言
--13.1开发语言
--单选题
-13.2 开发环境
--单选题
-13.3 腾讯开发组件介绍
--单选题
-13.4 网络通信+业务框架介绍
--多选题
-14.1 进程间通信(上)
-14.2 进程间通信(下)
-14.3 通信格式
-14.4 并发模型
-14.5 超时处理
-14.6 大系统小做(上)
--多选题
-14.7 大系统小做(下)
-14.8 架构层面的技术支持(上)
--单选题
-14.9 架构层面的技术支持(下)
-14.10 分布系统的关键能力
--多选题
-15.1 游戏人工智能综述
-15.2 人工智能在游戏中主要方法 上
--多选题
-15.3人工智能在游戏中主要方法 (下)
-15.4 人工智能在游戏制作中的应用领域1
--多选题
-15.5 人工智能在游戏制作中的应用领域2
-15.6 人工智能在游戏制作中的应用领域3
--多选题
-15.7 人工智能在游戏运营中的应用实践(上)
-15.8 人工智能在游戏运营中的应用实践(下)
--多选题
-16.1 游戏支撑系统(1)
--单选题
-16.2 游戏支撑系统(2)
--单选题
-16.3 游戏支撑系统(3)
--单选题
-16.4 游戏支撑系统(4)
--单选题
-16.5 游戏支撑系统(5)
-17.1 游戏逻辑服务器(上)
--单选题
-17.1 游戏逻辑服务器(下)
-17.2 外挂与反外挂(上)
-17.2 外挂与反外挂(下)
--多选题
-18.1运行环境
--18.1运行环境
--多选题
-18.2物理部署
--18.2物理部署
--多选题
-18.3系统的可运维性
--多选题
-18.4运维案列分析
--多选题