top of page
  • 作家相片Lingheng Tao

Unity Engine #2 System / Networking

已更新:1月13日


这一篇笔记主要是关于计算机系统以及网络的知识。


网络通信原理


Transmission Control Protocol / TCP


传输控制协议(Transmission Control Protocol)被简称为 TCP。这是一种网络通信协议。


【基本特性】

  1. 面向连接:在数据传输之前,必须先建立连接;

  2. 可靠传输:通过序列号、确认应答、重传机制等保证数据的正确传输。

  3. 有序传输:数据按照发送顺序到达接收方。

  4. 拥塞控制:动态管理数据传输速度,防止网络拥塞。

  5. 流量控制:通过窗口机制调整发送速率,防止接收方处理不及时。

【工作原理】

三次握手 3-way Handshake


第一次握手:客户端发送 SYN 包(seq = x)到服务器,并进入 SYN_SENT 状态;

第二次握手:服务器收到 SYN 包,回应 SYN+ACK 包(seq = y, ack = x+1),进入 SYN_RCVD 状态;

第三次握手:客户端收到 SYN+ACK 包,发送 ACK 包(ack = y+1),进入 ESTABLISHED 状态。


四次挥手 4-way Handshake

第一次挥手:发起方发送 FIN (seq = u)包,请求断开连接;

第二次挥手:接收方确认 FIN 包,发送 ACK (seq = v, ack = u+1) 包;

第三次挥手:接收方发送 FIN (seq = w, ack = u+1) 包;

第四次挥手:发起方确认 FIN 包,发送 ACK (seq = u+1, ack = w+1)包;


TCP 的包头结构

TCP 包头(TCP Header)一共 20 字节。其中

1. 源端口(Source Port): 16 Bits = 2 Bytes,对应类型为 short。

2. 目标端口(Destination Port):16 Bits = 2 Bytes,对应类型为 short。

3. 序列号(Sequence Number): 32 Bits = 4 Bytes,对应类型为 uint。

4. 确认号(Acknowledge Number): 32 Bits = 4 Bytes,对应类型为 uint。只有当ACK=1时确认号字段才有效。当 ACK=0 时,确认号无效。

5. 数据偏移 (Header Length)+ 保留位(Reserved)+ 控制位(Code Bits):4+6+6 = 16 Bits = 2 Bytes。这三个数据加在一起用一个 short 来存储,所以在进行它们的计算的时候要用到位操作。

注:控制位:UAPRSF 分别对应 URG 紧急包 / ACK 确认包 / RST 复位包 / SYN 同步包 / FIN 终止包。

6. 窗口大小 (Window):16 Bits = 2 Bytes,对应类型为 short。窗口字段用来控制对方发送的数据量,单位为字节。这意味着窗口大小只能是 0 - 65535 字节间的一个大小。TCP连接的一端根据设置的缓存空间大小确定自己的接收窗口大小,然后通知对方以确定对方的发送窗口的上限。

7. 校验和(Checksum):16 Bits = 2 Bytes,对应类型为 short。

8. 紧急指针(Urgent):16 Bits = 2 Bytes。当 URG = 1(在上面的控制位)时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。

总计 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 = 20 Bytes。


User Datagram Protocol / UDP


用户数据报协议(User Datagram Protocol)被简称为 UDP,是另一种网络通信协议。


【基本特性】

  1. 无连接:在数据传输之前,不需要先建立连接;

  2. 不可靠传输:并不能保证数据的可靠到达,也没有重新传输的机制。

  3. 无序传输:数据按照到达接收方的顺序并不固定。

  4. 无拥塞控制:无法管理数据传输速度,可能导致网络拥塞。

  5. 流量控制:包头信息少,处理速度很快。

【工作原理】

  1. 数据发送:直接发送数据,不保证对方能够接收;

  2. 数据接收:接收到数据也并不需要向对方确认,直接开始处理数据。

【UDP 包头结构】

仅有 8 字节。


与 TCP 类似,源端口和目标端口各占据 2 字节。校验和与长度各占据 2 字节。下面就是 UDP 数据了,所以包头很小。


【与 TCP 比较】

​TCP

UDP

​适用场景

适用于需要高可靠性的应用,如网页浏览、文件传输、电子邮件等。

​适用于实时性更高的应用,如视频流、在线游戏、VoIP 等。

性能差异

由于连接建立、确认应答等机制,延迟较高,但可靠性高。

延迟低,吞吐量高,但不保证数据完整性和顺序。

断线重连机制


对于大部分需要断线重连机制的应用来说,TCP 是一个更合适的选择,因为自带的可靠性传输机制可以简化设计。两种断线重连的机制可以如下设计。

TCP 断线重连

1. 检测连接状态

  • 客户端和服务器都需要有机制来检测当前的连接状态。

  • 可以通过定期发送心跳消息来确认连接是否依然活跃。

2. 识别断线

  • 当心跳检测失败或 TCP 连接发生错误时,客户端应识别为“断线”状态。

  • 服务器同样需要检测到客户端断线,并将该客户端标记为不活跃或断线状态。

3. 保存状态

  • 服务器需要在断线发生时保存客户端的当前状态。

  • 状态信息可以包括玩家位置、分数、物品等。

4. 尝试重连

  • 客户端在检测到断线后,应尝试重新连接服务器。

  • 可以设定一个重连尝试的时间间隔和最大尝试次数。

5. 身份验证和状态恢复

  • 在重连时,客户端需要发送身份验证信息给服务器。

  • 服务器验证客户端身份后,将客户端之前的状态恢复给客户端。

6. 恢复会话

  • 一旦重连成功并且状态恢复,客户端可以继续从断线前的状态开始。

7. 处理失败的重连尝试

  • 如果重连尝试失败,客户端可以提示用户并提供再次尝试或退出的选项。

UDP 断线重连


同步机制


在多人在线游戏,也被称为 MMO 的游戏开发中,我们通常会有一些网络同步的策略,用来确保不同玩家之间游戏的一致性和协同性。


帧同步


在帧同步中,

  • 所有玩家的游戏客户端按照相同 的固定帧率进行操作和更新游戏状态。

  • 每一帧中,玩家的输入被捕捉并发送到服务器。

  • 服务器接收到所有玩家的输入后,执行相同的游戏逻辑和模拟,以确保每个玩家的游戏状态保持一致。

  • 游戏客户端接受来自服务器的同步信息,更新本地游戏状态,然后绘制新的帧。

  • 帧同步通常用于实时竞技游戏,如射击游戏、格斗游戏、MOBA 等,因为它提供了高度的精确度和反应速度,同时也对网络延迟很敏感。

状态同步


在状态同步中,

  • 游戏客户端只发送自己的状态信息给服务器,并不是每一帧的输入。

  • 服务器维护完整世界的游戏世界状态,包括每个玩家的位置、属性、物品等。

  • 服务器负责更新游戏世界的状态,并将这些状态信息广播给所有玩家。

  • 游戏客户端接收服务器的状态更新,然后在本地模拟玩家的操作,以更新游戏界面。

  • 状态同步通常用于大规模多人在线游戏(MMORPG),因为它减少了网络带宽的使用,但也可能导致相对较高的延迟。

总结来说,帧同步强调实时性和精确性,适用于需要玩家精确控制和快速反应的游戏。状态同步更适用于需要处理大量玩家和复杂游戏世界状态的大型多人游戏。在实际游戏开发中,开发者可能会根据游戏类型和需求选择适合的同步策略或将两者结合使用,同一类型的游戏也有可能有不同的策略。


例如,MOBA 游戏中,王者荣耀、DOTA 采取的就是帧同步策略,而英雄联盟、DOTA2,则采取了状态同步的策略。

Apex 也采取了状态同步的策略。


这些竞技类游戏采用状态同步的策略,是因为 PC 上有着更稳定的网络,也在客户端使用预测算法来即时相应玩家的输入,同时等待服务器的最终状态确认。





 

参考资料:

24 次查看0 則留言

最新文章

查看全部

Unity Engine #5 Physics

#GameEngine #UnityEngine #GameProgramming 这篇笔记主要写一下关于碰撞检测和刚体(Rigidbody)组件的一些特性。

Comments


bottom of page