一、C/S 状态同步网络实现
1.单个客户端连入服务器步骤
1.客户端状态未初始化 Uninit
2.客户端发送hello标志给服务器,并将状态设置为Saying Hello状态
3.服务器收到后分配ID和关联Socket Address
4.服务器返回welcome标志和分配ID给客户端
5.客户端收到分配ID后保存ID,并将状态设置为Welcomed状态
2.有新客户端加入服务器步骤
服务器将新客户端对象信息同步给其他已连入的客户端
3.用户对客户端进行操作后网络交互的简化步骤
- 用户对客户端进行操作
- 客户端改变输入状态
- 客户端向服务器发送输入事件
- 服务器将输入状态保存到客户端代理中
- 服务器定时计算全局对象数据(服务器帧和收到数据包的频率可以不同,因此采用定时刷新)
- 服务器通知客户端对象数据发生改变
- 客户端刷新显示
二、对等网络实现
1.单个客户端连入对等网络步骤
- 客户端发送hello标志给主客户端
- 主客户端校验后返回允许进入或不允许进入,客户端将状态置为welcomed
- 客户端向当前网络内其他客户端发送相关初始化信息
- 所有客户端操作同意玩家准备
- 所有客户端将已准备标志发给主客户端
- 主客户端判断所有玩家已准备完毕,游戏正常开始
2.用户对客户端进行操作后对等网络的简化步骤
1.用户操作某个客户端
2.客户端检测命令是否改变状态
3.客户端将所有改变状态的命令存入命令列表
4.定时将命令列表同步给其他客户端(同时附带关键校验数据进行互相校验)
5.其他客户端在某一段时间内执行命令列表,模拟发生状态改变的客户端行为
执行x轮时,接受x+1轮数据,如果有数据丢失,网络管理器进入延迟状态。
- 如果连接被重置,删除该对等体
- 重传命令请求被忽略多次,删除该对等体
3.保持同步的关键点1:伪随机数生成器
PRNG(psendo random number generator)
- 种子相同
主对等体生成一个随机数 -> 其他对等体作为种子 - 每一轮被调用相同次数,考虑两个主要需要处理的情况:
a.跨平台
b.多版本
4.保持同步的关键点2:浮点数
浮点数在不同处理器上可能运算出不同结果
- 检验和(check sum)
每轮计算所有对等体游戏状态的检验和 - 循环冗余校验(CRC-cyclic redundancy check)
仅对重要数据进行循环冗余校验
*检测到不同步后的处理方法:
- 直接结束游戏
- 多个对等体之间“投票”:踢出不同步客户端