UE 可靠UDP实现原理
发送
我们的消息发送都是通过 UChannel 来处理的,通过调用 UChannel::SendBunch 统一处理。 发送的 Bunch 是以 FOutBunch 的形式存在的。当 bReliable 为 True 的时候,表示 Bunch 是可靠的。
发送逻辑直接从UChannel::SendBunch处开始分析
1、大小限制
UE的Bunch大小有限制, 最大Bunch为64K,SendBunch 的时候会去判断当前 Bunch 的大小是否超出限制。

2、Bunch处理(合并小Bunch,拆分大Bunch)
同一个Channel通道,可靠性一样,合并后没有超过单个 Bunch 的限制,可以合并为一个 Bunch。
如果是Actor初始化的包,需要同步CDO信息, 就不能合并。

同理,如果Bunch过大就会拆分,这些被拆分的 Bunch 的 bPartial 字段为1,表示这只是一个包的片段, 收包的时候会根据这个字段进行组包,拆分后的第一个 Bunch 的bPartialInitial 值为1,表示这是拆分后的第一个包, 最后一个包的 bPartialFinal 为 1。


3、可靠Bunch数量限制
如果设置了可靠 Bunch 上限 GCVarNetPartialBunchReliableThreshold,当本次要发送的 OutgoingBunches 的数量和之前 没收到Ack包的数量 超过阈值时,会暂停复制,直到收到了所有可靠消息的 Ack;
当可靠列表溢出的时候,连接会关闭。NumOutRec 为当前可靠的 Bunch 的数量,所以可靠 Bunch 的数量最多256个。

4、可靠 Bunch 预处理
在PrepBunch中对可靠包进行预处理
- OutReliable 保存着每个 Channel 的可靠 Bunch 数量,会去初始化 Bunch 的通道序列号 ChSequence,可以看出每个通道的可靠 Bunch 序列号是递增的。
- 每次发送一个可靠包时 NumOutRec(当前未收到Ack的可靠包数量) 会+1
- 将Bunch加入到 OutRec(发送的未确认的可靠消息数据)中,用于收到Nak后重传。只保存可靠的 Bunch。

5、UChannel::SendRawBunch
将ReceivedAck标记置为0

6、UNetConnection::SendRawBunch
设置 TimeSensitive 为1,先判断SendBuffer(存储BunchHeader和Bunch数据)是否可以装的下这次的Bunch+Header,如果装不下会调用 FlushNet 立即发送出去。然后将Header+Bunch写入SendBuffer中。

7、UNetConnection::Tick
如果有敏感标记TimeSensitive或者超时的时候会直接发送

8、UNetConnection::FlushNet
重置 TimeSensitive ,并且发送Packet。

接收
1、UNetConnection::ReceivedPacket
这一步进行了丢包检测。读取数据包头信息,并根据包头携带的序列号信息和最后一个成功接收到的序列号去判断序列号的增量,正常情况下,所有数据包都会按发出的顺序接收,所有增量会相差1。如果小于1,说明接收到的数据包发生了失序,引擎发送的每一个数据包序列号都是唯一的,不会重用,这种情况下引擎会忽略无效的数据包。


如果大于1,说明发生了丢包,不会立即处理当前的数据,会把当前的数据包加入队列 PacketOrderCache 中,等待收到差值为1的包再一起处理。

2、解析数据包头
然后调用PacketNotify.Update

每个到来的数据包都需要到 PacketNotify 中更新序列号信息。
1、根据包头携带的序列号数据计算出当前确认的序列号数量,然后根据 AckRecord 去更新 InAckSeqAck
2、如果超出数量上限 SequenceHistoryT::Size = 256,则视为收到 Nak
3、从序列号历史记录(History Storage)中判断是 Ack 还是 Nak,然后调用对应的处理函数

3、ReceivedAck
当接收到 Ack 的时候,会对当前确认的包 id 相同的 bunch 修改标志位 ReceivedAck,并且从 OutRec 列表中删除已确认的消息 bunch。

4、ReceivedNak
当我们发送一个可靠的 Bunch 的时候,会把它添加到 OutRec 中,这是一个已发送的未确认的可靠消息列表。当接收到 Nak 的时候,会为每个通道的包 id 为 NakPacketId 的未确认的可靠数据重新发送一次。丢包发生的时候,只会按 Bunch 去重新发送,Bunch 序列号还是原来的 Channel 序列号,而之前的 Packet 是不会重用的,只会生成新的 Packet,以及最新的 PacketId。意味着不会重新发送之前发送的数据包,也不会重用数据包序列号,数据包的发送每一次都是新生成的数据包,数据包序列号都是递增的,不会重复。
1、由于 OutRec 只保存了可靠的数据包,如果是不可靠的消息发生了丢包,引擎是不会重新发送它们的。
2、这里保存的是 RawBunch,如果 Bunch 是拆分的,丢弃了一部分,会导致整个 Bunch 的重新发送。

5、UChannel::ReceivedRawBunch
1、如果是可靠的消息,但是通道序列号不是有序的,则放入接收可靠消息列表 InRec 中,并按通道序列号 ChSequence 顺序存储,同样的,接收的可靠消息列表数量 NumInRec 一样不能超过可靠缓冲区大小256(RELIABLE_BUFFER)。
2、调用 ReceivedNextBunch 接收完之后,会再处理之前缓存的可靠消息列表 InRec,按顺序处理。
6、发送Ack、Nak消息
当收到一份数据的时候,我们会对数据进行确认,会回复 Ack 或者 Nak,写入到序列号历史记录中,由于历史记录最多 256 位,所以当 Ack 累计超过之后,会调用 FlushNet 立即发送。同时改变敏感标志位 TimeSensitive。


相关文章:
UE 可靠UDP实现原理
发送 我们的消息发送都是通过 UChannel 来处理的,通过调用 UChannel::SendBunch 统一处理。 发送的 Bunch 是以 FOutBunch 的形式存在的。当 bReliable 为 True 的时候,表示 Bunch 是可靠的。 发送逻辑直接从UChannel::SendBunch处开始分析 1、大小限…...
智慧博物馆信息化系统建设(1)
博物馆RFID藏品管理系统 博物馆藏品保管是一项十分复杂又繁琐的工作。从事保管工作除了经常、及时地进行藏品的登记、分类、编目、保养和修复等一系列工作外,还需要把有关藏品的信息迅速、正确地提供给利用者。要提高保管工作的效率,达到现代化的科学管理,从发展趋势看,进…...
【数据结构和算法】--- 二叉树(3)--二叉树链式结构的实现(1)
目录 一、二叉树的创建(伪)二、二叉树的遍历2.1 前序遍历2.2 中序遍历2.3 后序遍历 三、二叉树节点个数及高度3.1 二叉树节点个数3.2 二叉树叶子节点个数3.3二叉树第k层节点个数3.4 二叉树查找值为x的节点 四、二叉树的创建(真) 一、二叉树的创建(伪) 在学习二叉树的基本操作前…...
Cesium for Unity包无法加载
太上老君急急如律⚡令⚡ 🥙关闭UnityHub🧀启动梯子🥪cmd 启动UnityHub 🥙关闭UnityHub 🧀启动梯子 🥪cmd 启动UnityHub 把批处理启动文件👈中的exe的路径换成自己的安装目录!保存…...
Leetcode—40.组合总和II【中等】
2023每日刷题(七十七) Leetcode—40.组合总和II 算法思想 实现代码 class Solution { public:vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {vector<vector<int>> ans;vector<int…...
vscode连不上虚拟机,一直密码错误
最近在做毕设,但是vscode使用连接不上虚拟机,我以为是网络配置的问题,一顿查阅没找到原因。 后来查了一下ssh的日志,发现ssh有消息,但是也提示密码错误。 没找到密码配置格式什么的,经查看sshd配置文件发现…...
力扣每日一题 --- 972. 相等的有理数
本题中的一个难点是怎么判断是否相等,如果自己写判断的话是不是很麻烦,判断整数之后再去判断小数部分,那么我们这题的另一个难点就要登场了,第一个难点让本题的情况变得复杂,第二个难点让本题变得很难想到怎么判断&…...
EXECL 单元格字符串链接 CONCAT :应用:将一行数据转为json
源: 目标 函数表示 CONCAT("data", CHAR(10), "{", CHAR(10), " ", "ulAlarmId : ", A5, CHAR(10), " ", "ulAlarmLevel : ", D5, CHAR(10)," ", "bBo…...
基于Python实现人脸识别相似度对比
目录 引言背景介绍目的和意义 人脸识别的原理人脸图像获取人脸检测与定位人脸特征提取相似度计算 基于Python的人脸相似度对比实现数据集准备人脸图像预处理特征提取相似度计算 引言 背景介绍 人脸识别技术是一种通过计算机对人脸图像进行分析和处理,从而实现自动识…...
CSS 蜡烛效果
<template><view class="holder"><!-- 身子 --><view class="candle"><!-- 光源 --><view class="blinking-glow"></view><!-- 火星子 --><view class="thread"></view>…...
渗透测试之Kali如何利用CVE-2019-0708漏洞渗透Win7
环境: 1.攻击者IP:192.168.1.10 系统: KALI2022(vmware 16.0) 2.靶机IP:192.168.1.8 系统:Windows 7 6.1.7601 Service Pack 1 Build 7601 已开启远程协助RDP服务开启了3389端口 问题描述: KALI 如何利用CVE-2019-0708漏洞渗透Win7 解决方案: 1.打开kali,msf搜索…...
Docker(二)安装指南:主要介绍在 Linux 、Windows 10 和 macOS 上的安装
作者主页: 正函数的个人主页 文章收录专栏: Docker 欢迎大家点赞 👍 收藏 ⭐ 加关注哦! 安装 Docker Docker 分为 stable test 和 nightly 三个更新频道。 官方网站上有各种环境下的 安装指南,这里主要介绍 Docker 在…...
LeetCode 410. 分割数组的最大值
一、题目 1、题目描述 给定一个非负整数数组 nums 和一个整数 k ,你需要将这个数组分成 k 个非空的连续子数组。 设计一个算法使得这 k 个子数组各自和的最大值最小。 2、接口描述 class Solution { public:int splitArray(vector<int>& nums, int …...
linux shell脚本 基础认识
Linux 系统中的 Shell 是一个特殊的应用程序,它介于操作系统内核与用户之间,充当 了一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并…...
一文(10图)了解Cornerstone3D核心概念(万字总结附导图)
Cornerstone3D介绍 Cornerstone3D是一个专门为处理三维医学影像而设计的JavaScript库。 它是Cornerstone项目的一部分,旨在为医学影像社区提供高性能、可扩展且易于使用的开源Web工具,专注于提供交互式的3D医学图像浏览体验,适用于多种医学…...
牛客网-----跳石头
题目描述: 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有N块岩石(不含起点和终点的岩石)。在比赛过程中࿰…...
用ChatGPT教学、科研!大学与OpenAI合作
亚利桑那州立大学(简称“ASU”)在官网宣布与OpenAI达成技术合作。从2024年2月份开始,为所有学生提供ChatGPT企业版访问权限,主要用于学习、课程作业和学术研究等。 为了帮助学生更好地学习ChatGPT和大语言模型产品,AS…...
运维平台介绍:视频智能运维平台的视频质量诊断分析和告警中心
目 录 一、视频智能运维平台介绍 (一)平台概述 (二)结构图 (三)功能介绍 1、运维监控 2、视频诊断 3、巡检管理 4、告警管理 5、资产管理 6、工单管理 7、运维…...
GAMES104-现代游戏引擎:从入门到实践 - 物理引擎课程笔记汇总
文章目录 0 入门资料1 物理引擎基本概念Actor & shapesRigid body dynamicsCollision DetectionCollision Resolution 应用与实践Character controllerRagdoll 0 入门资料 GAMES104-现代游戏引擎:从入门到实践_课程视频_bilibiliGAMES104官方账号 - 知乎课程主页…...
【linux】Xorg的工作原理
介绍 在linux系统上执行nvidia-smi时,总有一个进程占用gpu。 1 N/A N/A 2174 G /usr/lib/xorg/Xorg 4MiB /usr/lib/xorg/Xorg 是与X Window System(简称X11或X)相关的一个应用程序。X Window System是一个…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
相关类相关的可视化图像总结
目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系,可直观判断线性相关、非线性相关或无相关关系,点的分布密…...
GraphRAG优化新思路-开源的ROGRAG框架
目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...
深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...
