Part 6.0 数据包基础
本章你将学到:
- 什么是数据包
- 数据包的结构
同步
- 同步指客户端、服务器通过数据包来将游戏状态发送给彼此,以达到两端游戏数据相同的过程。
举个例子:假如A玩家在游戏中生成了一个弹幕,那么A玩家就会向服务器发送一个数据包,告诉服务器他在游戏里生成了一个新的弹幕,服务器会将这个弹幕储存起来,然后发送数据包给其他玩家,告知A玩家生成了一个新的弹幕。
这个过程就是同步。 - 在上面的例子中,A玩家首先发送数据包和服务器同步,服务器再发送数据包和其他玩家同步,这样以来服务器、所有的客户端的对应的弹幕均相同,保证游戏里每一个玩家都能在相同的位置看见这个弹幕。
数据包
数据包是一种数据结构,就好比服主们喜欢用的JSON数据结构一样。数据包精简,体积小,适合传输;JSON体积更大,但更适合人阅读。
举个例子:TileGetSection(客户端请求获取区块) [8]
这个数据包用JSON表示如下
{
"Type": 8 //byte
"TileX": 114, //int
"TileY": 514, //int
}
他的数据包形式对应[9,0,8,114,0,0,0,2,2,0,0]
(byte[]),这是每个数字对应的含义
偏移量(Offset) | 大小(Size) | 字段 | 值(十进制) | 值(十六进制) | 说明 |
---|---|---|---|---|---|
0 | 2 | Packet Length | 9 ([9,0] ) | 0x0009 | 数据包总长度 = 9 字节 |
2 | 1 | Packet Type | 8 | 0x08 | 数据包类型(8号数据包表示客户端请求获取区块) |
3 | 4 | TileX | 114, 0, 0, 0 | 0x72 0x00 0x00 0x00 | int32大小为4字节,所以字段有4个 |
7 | 4 | TileY | 2, 2, 0, 0 | 0x02 0x02 0x00 0x00 | 同上 |
数据包的二进制格式不像 JSON 那样通过键(如 Type
、TileX
)标识字段,而是通过协议约定的字节偏移量(Offset)
和字段长度(Size)
来定位数据。
例如,要解析 TileX
:
- 根据协议,
TileX
的偏移量是3
(从 0 开始计数)。 - 读取接下来的
4
个字节(因为TileX
是int32
)。 - 按约定的字节序
Little Endian(小端序)
解析为整数值。//你只要知道是Little Endian(小端序)
就好了
注
在网络传输中,字节存储顺序有Little Endian(小端序)
和Big Endian(大端序)
之分,泰拉瑞亚的网络协议使用的是Little Endian(小端序)
## 数据包结构
偏移量 (Offset) | 大小 (Size) | 描述 (Description) | 类型 (Type) | 说明 |
---|---|---|---|---|
0 | 2 | PacketLength(数据包长度)(字节) | ushort | - |
2 | 1 | PacketType(数据包类型) | byte | 使用TSAPI.PacketTypes.PacketName 枚举值 |
3 | ? | Data(数据内容) | ? | 具体结构参考后续字段定义 |
偏移量 (Offset)
- 表示字段的起始位置(从 0 开始计数,类似数组索引)。
- 例如:
PacketType
的偏移量是2
,表示从第 3 个字节开始。
大小 (Size)
- 字段占用的字节数。
- 例如:
PacketLength
占 2 字节,Packet Type
占 1 字节。
类型 (Type)
- 数据类型,数据类型决定这个字段所占大小,下表是常见类型:
类型 (Type) | 大小 (Size) | 说明 |
---|---|---|
bool | 1 字节 (Byte) | 布尔值 (true /false ) |
byte | 1 字节 (Byte) | 无符号 8 位整数 (0 ~ 255) |
char | 2 字节 (Bytes) | UTF-16 字符 |
short | 2 字节 (Bytes) | 有符号 16 位整数 (-32,768 ~ 32,767) |
ushort | 2 字节 (Bytes) | 无符号 16 位整数 (0 ~ 65,535) |
int | 4 字节 (Bytes) | 有符号 32 位整数 (-2,147,483,648 ~ 2,147,483,647) |
float | 4 字节 (Bytes) | 32 位单精度浮点数 |
long | 8 字节 (Bytes) | 有符号 64 位整数 (-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807) |
double | 8 字节 (Bytes) | 64 位双精度浮点数 |
string | 变长 (可变) | UTF-16 字符串,实际大小取决于字符数量 |
数据包长度 (Packet length)
- 表示整个数据包的总字节数(包含自身)。
- 例如:如果长度字段的值是
[9, 0]
(小端序),则总长度 = 9 字节。
数据包类型 (Packet Type)
- 包号,代表数据包的功能(如
8
= 请求区块)。 - 建议用
TSAPI.PackeTypes.PacketName
提高代码可读性。
- 包号,代表数据包的功能(如
数据内容 (Data)
- 实际的有效载荷(Payload),也就是数据包携带的数据,结构因包类型而异。
- 需要查阅具体协议文档或者反编译代码才能解析。
- 例如:上面例子中的TileX,TileY