Games104——网络游戏的架构基础

news/2025/2/3 23:16:16/

这里写目录标题

多人网络游戏面临的挑战

  1. 保证每个用户事件的一致性
  2. 网络延迟和丢包
  3. 反作弊反信息泄露
  4. 复杂的设备,快速进行热更新迭代
  5. 复杂度高
    在这里插入图片描述

网络协议

OSI模型

在这里插入图片描述

Socket

通过一个简单的接口与另外一台机器建立连接就可以持续不断的传输数据
在这里插入图片描述

TCP/IP协议

特点:连接稳定、流量控制、包头长,保证信息的一致性
在这里插入图片描述
TCP的拥塞控制
在这里插入图片描述
对于对时间不太敏感但对稳定性有要求的游戏适合用TCP

UDP协议

端到端的协议
特点:不需要建立长时间的链接、不需要流量控制、包头轻、传播很快、但稳定性不行容易传达不到
在这里插入图片描述

在不稳定的网络情况下要求响应速度块适合用UDP,如吃鸡类

基于UDP的可靠连接

对于大型MMO不会使用单一协议,哪个适合用那个,游戏开发很多时候不会使用原生态协议
在这里插入图片描述

自动重复的要求

  • Stop and Wait ARQ
    等待ACK包到达后再去发下一个
    在这里插入图片描述
  • Go Back N ARQ
    发现一个包丢失后将窗口中的重新传一遍
    在这里插入图片描述
  • 选择重传ARQ
    告诉哪个包没有传到,重传没传到的那个包即可
    在这里插入图片描述
  • Forward Error Correction FEC
    在这里插入图片描述

Forward Error Correction FEC

XOR-FEC(异或运算)

在这里插入图片描述
在这里插入图片描述
如果丢失任何数据包,可以使用其他四个数据包进行恢复。
连续数据中只能丢失一个数据包。如果A和B同时丢失,算法将无法恢复。

不适用于丢包率高的情况

Reed-Solomon Codes

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以通过矩阵计算得到丢掉的数据
丢包率高的情况(比如移动端)也可以保证传输数据
在这里插入图片描述
可以根据具体需要DIY传输协议

时钟同步&RPC

对战游戏的重点就是要将时钟对准

RTT

我发一个包给对方多久能得到一个回包
在这里插入图片描述
RTT是自己写的,Ping更偏向底层

如何去对时间?

NTP

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
默认上行下行的时间是对等的,但事实上上下两路不一定是对等的,所以该算法不会很准确
在波动的网络下无法对准时间,只能推测

客户端和服务端建立连接时第一时间就要把钟对好
在这里插入图片描述

在这里插入图片描述

  1. 把NTP算法先跑一遍,算出来客户端时间和服务端时间的差别
  2. 调整客户端的时钟,因为网络会波动,所以多做几次NTP算法,记录每次RTT
  3. 去掉RTT比平均值高的值,再做一次平均,再用这个平均值对钟进行调整

RPC

对程序员而言在服务器和客户端之间网络传输会有以下的困难:
运行用不同语言编写
过程使用不同大小的数据类型
使用不同的字节顺序(字节序)
以不同的方式表示浮点数
具有不同的数据对齐要求
在这里插入图片描述
在这里插入图片描述
RPC让程序员不需要定义复杂的网络报体结构,从而专注的写游戏逻辑,只需要传几个参数即可

Stubs

相当于票据存根
在这里插入图片描述
Stubs Compiler读取 lDL 声明,并生成两个 stub
服务器程序员实现服务的程序,并将其与服务器端的stub链接起来。
客户端程序员实现客户端程序并将其与客户端的stubs链接起来
subs管理客户端和服务器之间远程通信的所有细节。

网络拓扑

P2P

早期使用的网络架构,研发商不需要维护服务器
在这里插入图片描述

Dedicated Server

在服务器端维护一个游戏世界,由研发商提供
在这里插入图片描述

允许不同地区的玩家在服务器之间建立高速的连接
在这里插入图片描述

快照同步

早期使用
客户端把自己的输入发给服务器,服务器把整个游戏世界的状态生成一个快照,然后把快照发给所有的客户端
保证了状态的一致性
在这里插入图片描述
服务端和客户端之间的帧率不同,快照生成的算力消耗大,所以使用Delta
在这里插入图片描述

缺点:快照数据量大,不适合用户数据量大的情况
客户端没有进行计算,浪费了客户端的算力

帧同步

服务器:信息的同步汇总转发

Initialization

初始化游戏内核心数据,保证局内数据高度一致化
服务器获取到所有客户端的输入,并将所有客户端的输入再发放给每个客户端,但最慢的用户会拖慢所有的进程
在这里插入图片描述
在这里插入图片描述
设置一个上限,如果有客户端在时间内没有输入则直接舍弃,但会产生一些潜在的bug和用户输入无效的问题
在这里插入图片描述
难点:要构建一个确定性的游戏世界
在这里插入图片描述
如何解决

  • 保证浮点数的高度一致性
    在这里插入图片描述
  • 保证随机数的确定性
    在这里插入图片描述
    在这里插入图片描述

Lag and Delay

无法规避网络抖动就可以使用buffer
在各个节点catch很多的数据,在本地网络抖动时smooth,以达成观看时稳定的效果
解决网络延迟和抖动的问题
在这里插入图片描述

将逻辑帧和渲染帧分割开来,画面不会抖动
在这里插入图片描述

断线重连

断线重连时可以根据客户端留存的快照减少断线重连时产生的差距,方便追上
在这里插入图片描述
服务端会在几个关键帧进行快照,当玩家过长时间断线时可以根据服务端的快照,帮助setup游戏的状态
在这里插入图片描述
另外一个重要的应用场景是观战
在这里插入图片描述
在这里插入图片描述
基于帧同步的机制可以拓展出这些游戏玩法

反作弊

投票机制
每隔一段时间每个客户发送一个校验码,如果有一个客户的校验码有误则将其踢掉
在这里插入图片描述
帧同步的特点是在客户端可以获取到局内所有的状态,游玩时使用插件就可以获取到这些状态,但现在的游戏会采取一些方法来规避这些问题

优点:可以做一些打击状态清晰的对抗,方便做游戏录屏
缺点:保持一致性很难

状态同步

同步用户的状态信息,如关键性的爆炸,死亡等
每一个玩家提供部分的信息,Server去模拟一个世界,只把与每个用户相同的信息发给他,防作弊的能力好于帧同步

在这里插入图片描述

  • Authorized
    玩家本地客户端
  • Replicated
    在其他玩家客户端上1P的复制体

整个世界的核心逻辑都是由Server计算的
不要求所有的客户端保证确定性

状态同步面临的问题
在这里插入图片描述

客户端预测

先预测半个RTT的时间再加上一个Command frame的动作,等服务端数据回来之后再对齐,尽可能让移动平滑
在这里插入图片描述

服务端和解

如果在Server的时间点状态不一致,那必须根据Server的要求反向矫正行为
在这里插入图片描述
服务端需要一个RingBuffer存储过去几帧,出现了状态不一致的问题后RingBuffer之后的数据全部无效化重新算一遍
在这里插入图片描述

丢包问题

用RingBuffer把输入存储下来,在获取不到输入时采用最后一次输入的状态
在这里插入图片描述
状态同步适合网络和游戏业务比较复杂的情况

状态同步和帧同步的区别


http://www.ppmy.cn/news/1569081.html

相关文章

97,【5】buuctf web [极客大挑战 2020]Greatphp

进入靶场 审代码 <?php // 关闭所有 PHP 错误报告&#xff0c;防止错误信息泄露可能的安全隐患 error_reporting(0);// 定义一个名为 SYCLOVER 的类 class SYCLOVER {// 定义类的公共属性 $sycpublic $syc;// 定义类的公共属性 $loverpublic $lover;// 定义魔术方法 __wa…

【Leetcode 每日一题】81. 搜索旋转排序数组 II

问题背景 已知存在一个按非降序排列的整数数组 n u m s nums nums&#xff0c;数组中的值不必互不相同。 在传递给函数之前&#xff0c; n u m s nums nums 在预先未知的某个下标 k ( 0 < k < n u m s . l e n g t h ) k\ (0 < k < nums.length) k (0<k<…

北京大学与智元机器人联合实验室发布OmniManip:显著提升机器人3D操作能力

近年来视觉语⾔基础模型&#xff08;Vision Language Models, VLMs&#xff09;在多模态理解和⾼层次常识推理上⼤放异彩&#xff0c;如何将其应⽤于机器⼈以实现通⽤操作是具身智能领域的⼀个核⼼问题。这⼀⽬标的实现受两⼤关键挑战制约&#xff1a;1. VLM 缺少精确的 3D 理解…

揭秘算法 课程导读

目录 一、老师介绍 二、课程目标 三、课程安排 一、老师介绍 学问小小谢 我是一个热爱分享知识的人&#xff0c;我深信知识的力量能够启迪思考&#xff0c;丰富生活。 欢迎每一位对知识有渴望的朋友&#xff0c;如果你对我的创作感兴趣&#xff0c;或者我们有着共同的兴趣点&…

基于OSAL的嵌入式裸机事件驱动框架——整体架构调度机制

参考B站up主【架构分析】嵌入式祼机事件驱动框架 感谢大佬分享 任务ID &#xff1a; TASK_XXX TASK_XXX 在系统中每个任务的ID是唯一的&#xff0c;范围是 0 to 0xFFFE&#xff0c;0xFFFF保留为SYS_TSK_INIT。 同时任务ID的大小也充当任务调度的优先级&#xff0c;ID越大&#…

本地缓存~

前言 Caffeine是使用Java8对Guava缓存的重写版本&#xff0c;在Spring Boot 2.0中取而代之&#xff0c;基于LRU算法实现&#xff0c;支持多种缓存过期策略。 以下摘抄于https://github.com/ben-manes/caffeine/wiki/Benchmarks-zh-CN 基准测试通过使用Java microbenchmark ha…

2025年01月31日Github流行趋势

项目名称&#xff1a;Qwen2.5项目地址url&#xff1a;https://github.com/QwenLM/Qwen2.5项目语言&#xff1a;Shell历史star数&#xff1a;13199今日star数&#xff1a;459项目维护者&#xff1a;jklj077, JustinLin610, bug-orz, huybery, JianxinMa项目简介&#xff1a;Qwen…

Nginx前端后端共用一个域名如何配置

在 Nginx 中配置前端和后端共用一个域名的情况&#xff0c;通常是通过路径或子路径将请求转发到不同的服务。以下是一个示例配置&#xff0c;假设&#xff1a; 前端静态文件在 /var/www/frontend/。 后端 API 服务运行在 http://127.0.0.1:5000。 域名是 example.com&#xff…