久游网

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 141|回复: 1

【GAMES104】18.网络游戏的架构基础

[复制链接]

3

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2022-10-19 22:08:35 | 显示全部楼层 |阅读模式
前言

多人在线游戏挑战


  • 网络同步
  • 稳定性

    • 网络延迟
    • 掉线和断线重连

  • 精确性

    • 作弊
    • 账号黑客

  • 多样性

    • 跨平台
    • 快速迭代

  • 复杂度

    • 高并发
    • 高可用性
    • 高性能

网络协议

TCP/IP协议



两台电脑怎么交互呢?
网络传输介质:电缆、光纤、Wifi


解决方案:中间件


OSI模型

7层,分层复用


Socket

socket的英文原义是“插座”
socket非常类似于电话插座。
以一个电话网为例:电话的通话双方相当于相互通信的2个程序,电话号码就是ip地址。
通话双方各买一个电话(初始化Socket),拨打电话进行连接(connnet),挂上电话结束通信(Close)




TCP(Transmission Control Protocol)


  • 面向连接的
  • 稳定、有序
  • 流量控制
  • 拥塞控制(网络拥塞,降低发包速度)
TCP包头


TCP重传机制

  • 正常发包1,2,3,4,5,6,7,8,收包都会带一个ACK序号,收包1,2,3,4,5,6,7,8
  • 如果5号包丢了的话,那么收到的就是1,2,3,4,4,4,4,4


TCP拥塞控制
滑动窗口
UDP(User Datagram Protocol)


  • 无连接
  • 不稳定、无序
  • 无流量控制
  • 无拥塞控制
UDP包头




现在一看,TCP有点像封装后的UDP,有点像Unity的Animation系统相较于PlayerableAPI。
要高自由度的话,可以在原始UDP上进行自定义,或者TCP,UDP混用
我们为啥要自定义协议?


  • 因为有多种需求:
  • 游服

    • 心跳(TCP)
    • 保持逻辑有序(TCP)
    • 高反应&低延迟(UDP)
    • 广播消息(UDP)

  • Web服务器

    • HTTP协议
    • 请求静态资源(文本、图片、链接、文件、视频)

ACK&序列号


  • ACK(Acknowledgment):一个在通信双方传递,用来表示已经收到消息的标识。
  • NAK(Negative Acknowledgment)
  • SEQ(Sequence number):一个用来追踪发送消息的计数器
  • Timeouts:超时时长
  • ARQ(Automatic Repeat Request):自动重传机制,如果等待超时或者丢包,就自动重发数据

    • 活动窗口协议的不同策略

      • Stop and Wait ARQ:滑动窗口长度为1,发一个,等收包,再发下一个
      • Go back N ARQ:N是窗口长度,一个ACK没收到,把窗口内的包重发一遍
      • Selective Repeat ARQ:只重传丢ACK的包,收到一个坏包就用NAK


FEC(Forward Error Correction)算法:UDP丢包处理


  • XOR FEC

    • 异或算法。
    • 发包的时候,多发一个要发的包的异或值。
    • 只能最多丢一个包,用其他包的异或,能算出丢包的值

  • Reed-Solomon Codes

    • 这个算法没看懂,用逆矩阵恢复数据

怎么自定义基于ARQ和FEC的UDP?


  • 使用Selective Repeat ARQ
  • 使用FEC算法用来做丢包的错误矫正
时钟同步&RPC

RTT(Round Trip Time)

RTT是从发一个包到收到这个包的回包的时间延迟
RTT和Ping的区别,用的协议不一样


网络时间协议(Network Time Protocol,NTP)

用来同步计算机时间
Reference Clock


NTP算法


假设收发的延迟时间是一样的,我们可以得到以下的Offset


那么本地的时间就矫正为


RPC(Remote Procedure Call)



IDL(Interface Definition Language)
比如谷歌的protobuf


RPC Stubs
我的理解是一个中间层,RPC都通过这个中间层去处理


RPC的流程

  • 建立连接:会话id,加密信息,压缩信息,秘钥
  • 发送消息:压缩、加密、传输,收到后进行解密,解压缩
  • 断线重连:会话id,token


网络拓扑


  • P2P
  • P2P 有主机服务器版
  • 专用服务器



P2P



P2P 有主机服务器版



专用服务器

游戏同步

快照同步


  • 客户端上传输入
  • 服务端根据输入模拟计算状态,把整个世界的快照同步下去
  • 客户端按照快照进行渲染
快照同步优化:

  • 不变的不同步,只同步变化的。有个致命问题,丢包就崩了
优缺点:

  • 客户端算力浪费
  • 服务端压力大
  • 带宽需求大,需要同步的数据太多
帧同步


  • 相同的输入+相同的帧率 = 相同的状态模拟
  • 客户端上传输入,服务端把所有输入下发,客户端模拟渲染
严格帧同步可能出现的问题
网速卡的会卡住大家进程
怎么处理?
Bucket同步,固定时间(100ms)收集输入上传,不管是否收到所有玩家的输入
我们需要根据实际项目,权衡用哪种同步,

  • 严格帧同步(连贯性)
  • Bucket同步(交互性)
保证一致输出的前提

  • 浮点数

    • 符合IEEE 754标准?
    • 不同平台的实现不同,需要保证一致
    • 定点数数学库
    • Look-up table

  • 随机数

    • 用相同的随机种子

  • 排序算法
  • 数学库
  • 物理模拟
  • 逻辑执行顺序
定位和Debug
CheckSum,自动定位问题


延迟(Delay)和抖动(Lag)处理

  • Cache
  • 逻辑渲染分离,在逻辑帧中插入渲染帧


重连和追帧

  • 客户端快照:一段时间,存个整个世界的快照,存到硬盘里,断线重连的时候,找到最近的快照,从这个快照进行追帧。
  • 快速追帧:渲染帧关闭,每帧跑多帧逻辑,追上游戏进程
  • 服务端快照:一段时间,存个整个世界的快照,存到硬盘里,断线重连的时候,服务器下发最近的快照,客户端从这个快照进行追帧。
有个问题,顶号的话,客户端快照是不是就失效了?
有了上面的快照技术,就能实现断线重连、观战、回放系统,用的都是一套机制
作弊问题

  • 多玩家情况:checkSum技术校验,算出的值不同的玩家就是作弊,踢掉
  • 2个玩家情况:这种情况,在服务器没有做校验的情况下,找不出谁开挂,但是只影响一个玩家,影响不大(别跟他玩)
  • 全图视野挂很难防:因为每个客户端都有全逻辑,全模拟




状态同步


  • 以服务器为权威
  • 从客户端接受输入和状态,在服务端模拟整个完整世界
  • 下发各个客户端需要的逻辑
  • 有一定的防作弊能力



  • Authorized(1P):玩家本地端
  • Replicated(3P):在其他玩家端的复制品
  • Server:权威服务器
Dumb Client Problem
客户端在没收到状态同步的时候,不能做任何操作。
就显得很呆,怎么解决这个问题呢?
客户端预测
服务端矫正
客户端预测
客户端总是比服务端提前预测半个RTT+一个命令帧的时间(守望先锋策略)


服务端矫正

  • Buffer

    • 把每次预测的状态存下来,服务端下发状态的时候,跟半个RTT前存的状态比对,如果一样,预测就是正确的

  • Ring buffer for states
  • Ring buffer for inputs
  • 如果预测错误,客户端需要接受服务端的状态,全部重新计算


丢包处理
丢包,服务器直接复制你最后的操作进行操作,比如你断线,让你一直往前跑
回复

使用道具 举报

2

主题

3

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 昨天 23:10 | 显示全部楼层
顶顶更健康
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|久游网

GMT+8, 2025-4-18 15:55 , Processed in 0.102167 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表