这是最新的Raknet协议文档。它包括有关协议中使用的数据类型的信息以及有关每个数据包及其相关字段的详细信息。
Todo:修改以使眼睛更好,并删除很多无用的东西。还可以组织事物,例如1位的枚举/常数,还可以删除重复的事物。
本文档假设您需要类似/相同的安全方法,这就是为什么如果要定位的服务器没有libcat或其他任何相同的原因,但是它们也启用了安全性,客户端将崩溃,因为它们只会为您提供cookie,没有身份证明或任何喜欢的东西。但是您可以提取支持这两种情况的请求。
| 类型 | 尺寸 | 笔记 |
|---|---|---|
| UINT8 | 1字节 | 未签名的8位整数 |
| UINT16 | 2个字节 | 未签名的16位整数 |
| Uint24 | 3个字节 | 未签名的24位整数,最小值为0,最大值为16777215 |
| Uint32 | 4个字节 | 未签名的32位整数 |
| Uint64 | 4/8字节 | 未签名的64位整数(32位系统的4个字节,8个字节,用于64位系统) |
| UINT16弦 | 多变的 | UTF-8编码的字符串,长度为2个字节之前的字符串之前 |
| 魔法 | 16个字节 | 具有特定序列的无符号8位整数的阵列[0x00, 0xFF, 0xFF, 0x00, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFD, 0x12, 0x34, 0x56, 0x78] |
| 零件为零 | 多变的 | 空字节用于填充,您选择的尺寸很大 |
| 布尔 | 1字节 | 编写或读取为单个未签名的8位整数,值为0或1(零用于表示false,而一个用于表示true) |
| 地址 | 7-29字节 | IPv4:1字节(地址版本),4个字节(IP地址),2个字节(端口),IPv6:1字节(地址版本),无符号地址家族的缩写(小时),端口号无签名的缩写,无符号的flow Integer for Flow Infoger,16个字节,地址为16个字节,无标准的Integer for Scope ID。 |
| 少量 | 1位 | 完成缓冲区后,写或阅读钻头 |
| 漂浮 | 4个字节 | IEEE 754单位浮点数 |
如果您想更快地实施,可以立即定义这些内容,而无需阅读它们的制作方式。
| 姓名 | 价值 |
|---|---|
| mtusize | 1492 |
| udpheadersize | 28 |
| publickysize | 294 |
| requstchallengize | 64 |
| 响应关联键 | 128 |
| maxnumberoflocaladdresses | 10 |
| 识别型 | 294 |
| 顾客介绍 | 32 |
| DefaultProtolocoLversion | 6 |
| 数字 | 32 |
| 姓名 | ID | 类型 |
|---|---|---|
| 未连接 | 0x01 | 离线 |
| 未连接的培根连接 | 0x02 | 离线 |
| 未连接的庞 | 0x1c | 离线 |
| 连接 | 0x00 | 在线[/到数据报] |
| 连接 | 0x03 | 在线[/到数据报] |
| OpenConnectionRequestone | 0x05 | 离线 |
| OpenConnectionReplyly | 0x06 | 离线 |
| OpenConnectionRequesttwo | 0x07 | 离线 |
| OpenConnectionReplyplytwo | 0x08 | 离线 |
| ConnectionRequest | 0x09 | 在线[/到数据报] |
| 遥控系统RequirespublicKey | 0x0a | 离线 |
| Oursystemrequiressecurity | 0x0b | 两个都 [?] |
| ConnectionAttEmptFail | 0x11 | 离线 |
| 已经连接了 | 0x12 | 离线 |
| ConnectionRequestaccept | 0x10 | 在线[/到数据报] |
| 新IncomingConnection | 0x13 | 在线[/到数据报] |
| 断开指示 | 0x15 | 在线的 |
| ConnectionLost | 0x16 | 两个都 [?] |
| 不兼容的交流 | 0x19 | 在线的 |
等待客户的无关数据包。
等待客户端的OpenConnectionRequestone数据包。
等待客户端的OpenConnectionRequesttwo数据包。
等待客户端的数据报。
将未连接的数据包发送到服务器。
将OpenConnectionRequestone数据包发送到服务器。
将OpenConnectionRequestTwo数据包发送到服务器。
将数据报发送到服务器。
该数据包用于确定服务器是否在线。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| Onlyplyplyplynopenconnections | 布尔 | N/A。 | 如果设置为true,则只有在客户端的连接到服务器当前打开时,服务器才会发送回复。这有助于防止向关闭联系的客户发送响应。该请求的结果消息ID将是UnconnectedPingOpenConnections 。如果设置为false,则标识符无需更改。 |
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 客户结构时间 | Uint64 | 大恩迪安 | 客户时间戳用于计算延迟 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| 客户端 | Uint64 | 大恩迪安 | 客户的唯一标识符 |
该数据包是对未连接的PING数据包的响应。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| ServerSendTime | Uint64 | 大恩迪安 | 服务器时间戳用于计算延迟 |
| Serverguid | Uint64 | 大恩迪安 | 服务器的唯一标识符 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| 反应室 | UINT16弦 | 大恩迪安 | 通常用于服务器信息的响应数据 |
该数据包用于使客户端和服务器之间的连接保持活力。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 客户结构时间 | Uint64 | 大恩迪安 | 客户时间戳用于计算延迟 |
该数据包是对连接的PING数据包的响应。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 客户结构时间 | Uint64 | 大恩迪安 | ping的客户时间戳 |
| ServerSendTime | Uint64 | 大恩迪安 | 服务器时间戳用于计算延迟 |
该数据包用于启动客户端和服务器之间的握手过程。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| 协议vers | UINT8 | N/A。 | 客户支持的协议版本 |
| mtusize | 零件为零 | N/A。 | 客户的最大传输单元(MTU)大小 |
使用零件时,添加到MTU尺寸时,当前的阅读位置加28(UDP标头尺寸)进行读数。对于写作,请减去MTU大小,并使用当前的缓冲区写入位置(或其大小)加28(UDP标头尺寸)加上当前的缓冲区大小。要验证数据包缓冲区,请检查其大小是否为28(UDP标头尺寸)以及当前的缓冲区大小。
该数据包是对一个数据包的打开连接请求的响应。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| Serverguid | Uint64 | 大恩迪安 | 服务器的唯一标识符 |
| ServerHassecurity | 布尔 | N/A。 | 服务器是否需要安全性 |
| mtusize | UINT16 | 大恩迪安 | 服务器的最大传输单元(MTU)尺寸 |
此数据包是对一个包含其他安全信息的打开连接请求的响应。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| Serverguid | Uint64 | 大恩迪安 | 服务器的唯一标识符 |
| ServerHassecurity | 布尔 | N/A。 | 服务器是否需要安全性 |
| Hascookie | 布尔 | N/A。 | 该数据包是否包括cookie |
| 曲奇饼 | Uint32 | 大恩迪安 | cookie值 |
| ServerPublicKey | UINT8 [294] | N/A。 | 用于加密的公钥 |
| mtusize | UINT16 | 大恩迪安 | 服务器的最大传输单元(MTU)尺寸 |
该数据包用于完成客户端和服务器之间的握手过程。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| ServerAddress | UINT8 [7-29] | N/A。 | 服务器IP地址和端口组合 |
| mtusize | UINT16 | 大恩迪安 | 客户的最大传输单元(MTU)大小 |
| 客户端 | Uint64 | 大恩迪安 | 客户的唯一标识符 |
该数据包用于完成客户端和服务器之间的握手过程。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| 曲奇饼 | Uint32 | 大恩迪安 | cookie值 |
| 包含挑战 | 布尔 | N/A。 | 系统是否需要握手挑战 |
| 挑战 | uint8 [64] | N/A。 | 系统握手挑战字节 |
| ServerAddress | UINT8 [7-29] | N/A。 | 服务器IP地址和端口组合 |
| mtusize | UINT16 | 大恩迪安 | 客户的最大传输单元(MTU)大小 |
| 客户端 | Uint64 | 大恩迪安 | 客户的唯一标识符 |
注意:如果OpenConnectionReplylyone数据包具有安全性,但是该数据包不包含挑战,则客户端应立即发送远程启动repubrespublickey数据包,以通知服务器在OpenConnectionRequesttwo数据包中没有挑战。
您可以编写自己的计算连接结果的方式,但这是标准方式。
计算连接之路:
bitwise and使用contains address检查下面的检查,并contains guid Boolean值。clientGuid已经与具有不同客户端地址的客户端关联,请将连接状态设置为3。clientGuid关联,请将连接状态设置为4。一旦计算了
ConnectionOutcome,您将需要检查它是否等于1,然后发送OpenConnectionReplyTwo数据包。
如果
ConnectionOutcome不是0,请发送AlreadyConnected数据包。
此数据包是对两个数据包的打开连接请求的响应。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| Serverguid | Uint64 | 大恩迪安 | 服务器的唯一标识符 |
| ClientAddress | UINT8 [7-29] | N/A。 | 客户端IP地址和端口组合 |
| mtusize | UINT16 | 大恩迪安 | 服务器的最大传输单元(MTU)尺寸 |
| 需要吸收 | 少量 | N/A。 | 连接是否需要加密 |
| 加密钥匙 | UINT8 [128] | N/A。 | 客户端的加密密钥 - 仅在设置为true的requiresEncryption时,仅编写或读取。 |
该数据包用于在客户端和服务器之间建立具有启用或禁用安全性的服务器之间的连接。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 客户端 | Uint64 | 大恩迪安 | 客户的唯一标识符 |
| 客户结构时间 | Uint64 | 大恩迪安 | 客户要求连接时的时间戳 |
| dosecurity | 布尔 | N/A。 | 连接是否需要安全性 |
| 客户防护 | uint8 [32] | N/A。 | 客户身份验证证明 |
| 行事 | 布尔 | N/A。 | 数据包是否需要身份证明 |
| 身份 | UINT8 [294] | N/A。 | 客户身份证明 |
注意:如果身份证明是无效的,并且设置为TRUE,请立即发送带有
ClientIdentityIsInvalid类型ID的RemoteSystemRequiresPublicKey设备doIdentity。如果doIdentity设置为false,并且没有身份证明,请发送带有ClientIdentityIsMissing类型ID的RemoteSystemRequiresPublicKey系统Repurepbublickeykekekekekekekeky。
该数据包用于抛出与公共密钥请求有关客户端身份验证和标识的错误。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| TypeID | UINT8 | N/A。 | 公钥请求的类型 |
| 姓名 | ID |
|---|---|
| ServerPublicKeySissing | 0 |
| 客户识别症 | 1 |
| 客户InternistityisInvalid | 2 |
当服务器不需要安全性,但仍然是强制性的,该数据包将发送。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| ClientAddress | UINT8 [7-29] | N/A。 | 客户端IP地址和端口组合 |
| Serverguid | Uint64 | 大恩迪安 | 服务器的唯一标识符 |
当尝试加入服务器的尝试计数高于一定数量时(取决于您的实现),或者客户端不包含分配的地址时,发送此数据包;如果在发送OpenConnectionRequestOne数据包之前满足要求,这就是您检查并发送的内容。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
当客户端已经连接时,将发送此数据包。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| 客户端 | Uint64 | 大恩迪安 | 客户的唯一标识符 |
此数据包是对启用安全性的连接请求的响应。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| ClientAddress | UINT8 [7-29] | N/A。 | 客户端IP地址和端口组合 |
| ClientIndex | UINT16 | 大恩迪安 | 分配给客户的唯一标识符 |
| servermachineaddresses | 地址[10] | N/A。 | 服务器本地计算机地址 |
| 客户结构时间 | Uint64 | 大恩迪安 | 客户时间戳 |
| ServerSendTime | Uint64 | 大恩迪安 | 服务器的时间戳 |
当新客户端连接到服务器时,此数据包将发送给所有其他客户端。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| ServerAddress | UINT8 [7-29] | N/A。 | 服务器IP地址和端口组合 |
| 客户端machineaddresses | 地址[10] | N/A。 | 客户本地机器地址 |
| 客户结构时间 | Uint64 | 大恩迪安 | 客户时间戳 |
| ServerSendTime | Uint64 | 大恩迪安 | 服务器的时间戳 |
将该数据包发送或接收到服务器后,您需要通过发送定期ConnectedPing数据包来保持连接的活力。这些数据包本质上是说“嘿,我仍然在这里并连接到服务器”的一种方法。该服务器还将ConnectedPong数据包发送回响应,以确认连接仍然处于活动状态。由于不活动或网络问题,这种乒乓球过程有助于防止连接定时出现。
当客户端与服务器断开连接时,该数据包将发送。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
当与客户端的连接丢失时,将发送此数据包。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 客户端 | Uint64 | 大恩迪安 | 客户的唯一标识符 |
| ClientAddress | UINT8 [7-29] | N/A。 | 客户端IP地址和端口组合 |
当客户端尝试使用不兼容协议版本连接到服务器时,将发送此数据包。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 协议vers | UINT8 | N/A。 | 服务器支持的协议版本 |
| 魔法 | uint8 [16] | N/A。 | 识别数据包的魔术序列 |
| Serverguid | Uint64 | 大恩迪安 | 服务器的唯一标识符 |
此数据包用于在客户端和服务器之间发送和接收数据。它可以是三种类型之一:有效datagram,ackeddatagram或nackeddatagram。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| 伊斯瓦利德 | 少量 | N/A。 | 永远是真的 |
| isack | 少量 | N/A。 | 如果是真的,则数据包是一个ackeddatagram |
| isnack | 少量 | N/A。 | 如果是真的,则数据包是一个nackeddatagram |
如果
isAck和isNack都是错误的,则数据包是有效的Datagram。
该数据包是对有效datagram的响应,表明服务器已收到数据。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| 需要bandas | 少量 | N/A。 | 如果为true,则数据包包括b和值 |
| b | 漂浮 | 大恩迪安 | 未使用 |
| 作为 | 漂浮 | 大恩迪安 | 数据到达率 |
| 范围 | 范围 | N/A。 | 接收到的范围值阵列 |
该数据包是对有效datagram的响应,表明服务器尚未收到所有预期数据。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| 范围 | 范围 | N/A。 | 未收到的范围值阵列 |
该结构用于表示Ackeddatagram的范围和nackeddatagram的缺失范围。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| 尺寸 | UINT16 | 大恩迪安 | 数组中的范围数 |
| ISSINGLE | 布尔 | N/A。 | 如果最小等于最大,则将其设置为true |
| 最小 | Uint24 | 小末日 | 最小值 |
| 最大限度 | Uint24 | 小末日 | 范围内的最大值 - 如果是单个的,则不会写 |
此数据包用于在客户端和服务器之间发送和接收数据。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ispacketpair | 少量 | N/A。 | 如果是真的,则数据包是两个相关数据包之一 |
| 连续的 | 少量 | N/A。 | 如果是真的,则数据包是连续发送数据包 |
| 需要bandas | 少量 | N/A。 | 如果为true,则数据包包括b和值 |
| 朗格伯 | Uint24 | 小末日 | 数据报的序列编号 |
| 胶囊 | datagramcapsule [] | N/A。 | 包中的胶囊阵列 |
检查损坏的安排渠道:(有效的数据报必须进行`序列和安排(无ACK收据))
如果arrangmentChannel更大或等于可用的2 ^ 5的排列流数量,则它将被核断(跳过并执行所需的操作)。
数组最大值的每个有效数据报道类型都是布置流的数量,不得更大或等于。
在接收到的数据报中查找孔数:(有效的数据报必须Reliable or in sequence继续前进之前)
您将需要在有效的数据报中检查孔计数,该数据报的Reliable or in sequence ,其原因是检查其订单,并作为检查是否有某种有效的数据报或错误的rangeNumber用于发送或其他原因。
receivedPacketsBaseIndex :仅当有效的数据报Reliable or in sequence
receivedPacketQueue :它是将有效数据报的rangeNumber存储为列表中的关键,它的值是正确的,而不是数据报,它可能是错误的,但是在遇到了某些代码之后,它将在下面说明(错误意味着我们可以成功地获得它,这意味着我们无法成功地获得DS_Queue ),并且它的数据结构是Inpplant riptim promptim in Inpplant rimptim prompt ryppections prompt in Inpply rypt promptimpection primst in Impand prinps prinps squequee in Inpplaaknet。
要查找孔计数,减去带有receivedPacketsBaseIndex的当前接收到的有效数据报的rangeNumber ,并且每次没有孔计数时属性增量(仅在Reliable or in sequence ,只有receivedPacketsBaseIndex递增)。
receivedPacketQueue中删除,然后添加(pre-)将receivedPacketsBaseIndex递增。bitwise right shifted 1的uint24的最大值,则它是一个重复的数据包(跳过并执行所需的操作)。receivedPacketQueue小屋大小receivedPacketQueue的索引/钥匙,并且不等于false,请通过用receivedPacketQueue中的孔计数的键填充孔,其值等于false。如果未满足这些条件的情况:
bitwise and uint32最大值)大于receivedPacketQueue大小,请通过在队列中推动真实值来填充它。之后,您可以创建一个循环,并检查receivedPacketQueue大小是否大于0,并且receivedPacketQueue的第一个值为false,然后删除receivedPacketQueue的最后一个元素,然后将receivedPacketsBaseIndex递增。
之后,您可以正常处理有效的数据报。
该结构代表有效Datagram中的胶囊。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| 可靠性 | 3位 | 大恩迪安 | 使用的可靠性类型 |
| 分段 | 少量 | N/A。 | 如果是真的,则分段数据包 |
| 尺寸 | UINT16 | 大恩迪安 | 缓冲区的大小在那里 |
| ReliablecapsuleIndex | Uint24 | 小末日 | 用于可靠数据包的索引(这意味着为此使用可靠性) |
| 序列capsuleIndex | Uint24 | 小末日 | 用于测序数据包的索引(这意味着为此使用可靠性) |
| 安排 | 胶囊 | N/A。 | 用于测序和布置数据包的胶囊的排列(这意味着为此使用可靠性) |
| 部分 | 胶囊 | N/A。 | 胶囊分割时使用的胶囊段 |
| 缓冲 | 缓冲 | N/A。 | 包含想要通过网络发送的数据的缓冲区数据 |
该结构代表在有效datagram中胶囊的布置。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| 布置CapsuleIndex | Uint24 | 小末日 | 排列胶囊的索引 |
| 安排通道 | UINT8 | N/A。 | 用于安排的渠道 |
该结构表示有效datagram中胶囊的分割。
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| 尺寸 | Uint32 | 大恩迪安 | 段的大小 |
| ID | UINT16 | 大恩迪安 | 与该细分市场关联的唯一标识符 |
| 指数 | Uint32 | 大恩迪安 | 索引的索引 |
在Raknet中发送的每个数据报都分配了一个可靠性TypeID,该可靠性指定了协议应如何处理数据。下表列出了可用可靠性类型及其属性:
| 姓名 | ID | 是可靠的 | 被安排 | 被测序 | 特征/特征 |
|---|---|---|---|---|---|
| 不可靠 | 0 | 不 | 不 | 不 | 此可靠性TypeID将发送数据报,而无需保证它们将到达目的地。他们不能保证以任何特定的顺序或根本交付 |
| 无杂志 | 1 | 不 | 是的 | 是的 | 此可靠性TypeID发送数据报,无保证它们将到达目的地,但可以确保以发送的顺序交付它们 |
| 可靠的 | 2 | 是的 | 不 | 不 | 此可靠性TypeID发送保证按发送订单交付的数据报。如果丢失了数据报,Raknet将重新将其重新发送到接收器确认为止 |
| Reliablearranged | 3 | 是的 | 是的 | 不 | 此可靠性TypeID发送保证按发送订单交付的数据报。如果丢失了数据报,Raknet将不会重新将其重新启动和所有数据报。 |
| 透露倍增 | 4 | 是的 | 是的 | 是的 | 此可靠性typeID发送保证按照发送的顺序发送的数据报,并确保它们被顺序交付 |
| 不可靠的WithackReceipt | 5 | 不 | 不 | 不 | 此可靠性TypeID发送数据报,无保证,它们将到达目的地,但是接收者在收到此数据报时会发送确认收据 |
| 可靠的WithackReceipt | 6 | 是的 | 不 | 不 | 此可靠性TypeID发送保证按发送订单交付的数据报,并且接收者在收到此数据报时发送确认收据 |
| ReliaBlearrangedWithAckReceipt | 7 | 是的 | 是的 | 不 | 此可靠性typeID发送保证以发送的订单交付的数据报,但所有数据报都没有被确认,并且接收者在收到此数据杂志后发送确认收据 |
在这里,您可以找到在文档中其他地方使用的所有可靠性定义。
Sequenced且可靠的安排和可靠的ACK RECEPITRaknet使用选择性重复重新传输来确保数据报的可靠交付。发送数据报时,将分配一个序列号。如果在特定超时期内未确认数据报,则Raknet将使用相同的序列编号重新发送数据报。当接收器收到具有相同序列编号的重复数据报时,它可以丢弃它,因为它已经确认了该序列编号。
Ackqueue和Nackqueue用于跟踪已确认哪些数据报,尚未确认哪些数据报。 Ackqueue存储了已成功确认的数据报序列编号的列表,而Nackqueue存储了尚未确认且需要重新发送的数据报序列号列表。当收到具有已经确认的序列号的数据报时,可以将其丢弃。
PacketPair是Raknet用于提高数据报重传效率的一种技术。确认数据报时,Raknet也将在序列中发送下一个数据报。这使得接收器可以立即开始处理下一个数据报,从而减少延迟并改善吞吐量。
连续记录是Raknet的功能,它允许在不等待确认的情况下连续发送数据报。在某些情况下,这可以提高性能,但也可以导致数据包丢失和重新转载,因为发件人在发送下一个数据报之前没有等待反馈。
Raknet使用重新组装机制来重建可能不订单的分段数据报。分段数据报时,每个段都被分配一个唯一的标识符。当接收器接收一个细分市场时,将其进行缓冲,直到收到具有相同标识符的所有段为止。一旦收到所有段,它们就会重新组合到原始数据报中。
流量控制是一种用于管理发件人和接收器之间数据传输速率的RAKNET机制。它确保接收器可以以其可以处理的速度处理传入的数据,从而防止或溢出接收器的缓冲区。流量控制有助于保持发件人的传输速度和接收器的处理能力之间的平衡,从而优化通信的总体效率和稳定性。
拥堵经理拥有拥堵控制,检查跳过的范围数字以发送nacks以及其他东西。
托多:添加文档
拥塞控制是一种RAKNET技术,用于通过平衡数据传输速率来防止网络拥塞。使用TCP拥塞控制,数据包掉落,速率限制,交通形成,QoS和负载平衡等技术。这些技术可确保可靠的数据传递和Raknet中有效传输。
Raknet中的分割通过将大信息分为较小的细分市场来增强数据传输。这些细分市场带有标头表示位置和尺寸,可确保在接收器的末端成功重新组装。通过将缓冲区大小与最大传输单元(MTU)大小进行比较,如果缓冲区超过MTU,则将其分为传输段。 Raknet中的这种机制可防止数据丢失,管理大量有效载荷并确保网络应用程序中可靠的传输。
“ B”表示可以在网络链接上每秒传输的链接容量或最大数据。链接容量由多种因素决定,包括网络基础架构,网络配置和可用资源。通过使用浮点数,可以更准确,准确地表示网络容量,从而更好地利用可用资源。
“ AS”代表数据到达率,这是发件人生成和发送数据的速率。浮点数的使用可以更精确地表示到达率,这可能会根据应用程序要求和网络条件而变化。通过将到达率与链接容量进行比较,发件人可以确定可以通过网络链接发送的数据量,而不会导致绩效的拥塞或退化。
要确定胶囊的大小,您可以按照以下步骤操作:
reliableCapsuleIndex 。sequencedCapsuleIndex 。arrangedCapsuleIndex ,然后按1个步骤进行arrangementChannel 。size为4步, id的2个步骤以及该段index的4个步骤。 UserPacketenum ID为0x86 ,它标志着您可以在哪里开始使用自定义数据包ID的开始。
建议考虑到完成的实现,然后发送并接收它,建议创建一个PacketAggregator 。
您可以将ID放置一个ID,例如: UserPacketEnumID +您自己的ID(它一定不能使UserPacketEnumID超过uint8 limit )
例如: UserPacketEnumID + 22 = 0x9c
一个简单的数据包结构,展示了PacketAggregator内容:
| 场地 | 类型 | 伊尼亚语 | 笔记 |
|---|---|---|---|
| ID | UINT8 | N/A。 | 数据包的唯一标识符 |
| 压缩贡法 | UINT8 | 压缩算法[可以无,openssl,zlib,gzip,ntappy,任何东西] | |
| 流 | 缓冲[] | 一个数据包流数组(流数组中的每个元素代表一个编码/的数据包缓冲区,并且要在compressionAlgorithm中解码) |
之后,您将其发送到有效的数据报胶囊/S缓冲区中
要发送非raknet数据包,请首先通过比较胶囊缓冲区大小是否大于MTU大小2负2,加3,加4倍1(对于数据报的数据标头长度),并减去11,如果使用安全性,则减去11。然后,用胶囊大小减去给定值。如果需要进行分割,请在将其添加到数据报队列以进行传输之前,然后将其添加到胶囊的流中。如果不需要分割,请将其直接添加到队列中。请记住,分段的数据包不可不可靠;如果是,请将它们转换为可靠的数据包,以确保所有数据包零件的成功和有序交付。
将其分为部分的方式:
获取胶囊尺寸以及胶囊缓冲尺寸,然后您用来检查是否大于胶囊缓冲区大小并定义它们的大小。
要计算需要制作多少个片段:减去胶囊缓冲尺寸的大小,然后将其与过去检查是否大于胶囊缓冲尺寸大的大小进行分配,然后用1(不是两次)将它们总结为1(不是两次),或者您可以减去1并在最后添加1个
然后在循环外定义current segment index ,默认为0
then do a loop that will use the count of how many segments then the segmentation process will start:
after that define a variable representing start offset and it is equals to current segment index multiplied by the size that you used to check if is greater than the capsule buffer size
after that define a variable representing bytes to send that is equals to capsule buffer size subtracted by start offset
check if bytes to send is greater than the size that you used to check if is greater than the capsule buffer size and if true set the bytes to send value to the size that you used to check...
after that create a new variable representing the end offset
check if the bytes to send is not the size that you used to check if is greater than the capsule buffer size then set the end offset to the capsule buffer size subtracted by the current segment index multiplied by the size that you used to check if is greater than the capsule buffer size
if the check fails then the end offset will be the bytes to send
after that slice the capsule buffer with the start offset and end offset then you can do the feilds in the capsule.
you will need an array that has the capsules that contains the segments that will then be sent in queue.
the segment id will be the sender last segment id property that will increment outside the loop every time.
Here are a list of resources to help you better understand the RakNet protocol: