--- tags: [] date created: 星期一, 十一月 24日 2025, 4:25:06 下午 date modified: 星期一, 十一月 24日 2025, 4:29:22 下午 --- # 2.4.3 丢包检测与时序完整性机制 (Packet Loss Detection & Sequencing Integrity) 这是显控终端的“网络听诊器”。在单向 UDP 传输模式下,显控端不仅是被动的数据消费者,更是链路质量的唯一评判者。它需要利用 2.4.2 定义的协议头字段,实时诊断出“谁丢包了”、“延迟多少”、“服务器是否过热”,并将这些隐性故障转化为显性的运维指标。 ## 一、 约束输入与对齐 (Constraints & Alignment) 基于 TDP-2.4-DIST(分布式补丁)和 ECN-2025-001(显控扁平化),我们需对齐以下硬性约束: 1. **多源独立性**:丢包检测必须**按站点 (StationID) 隔离**。站点 A 的网络抖动绝不能触发站点 B 的告警。 2. **时钟假设**:显控终端作为系统的一部分,假设已通过 NTP/PTP 与总控服务器同步。因此,`timestamp_us` 可用于计算绝对的端到端延迟(Glass-to-Glass Latency)。 3. **处理策略**:显控端对于乱序包执行**立即丢弃**策略,以保证态势图的实时性。 --- ## 二、 权衡分析与选项呈现 (Trade-off Matrix) ### 议题 1:丢包判决逻辑 (Loss Judgment Logic) |**选项**|**A. 简单间隙检测 (Simple Gap)**|**B. 统计窗口平滑 (Sliding Window Stats) (推荐)**| |---|---|---| |**机制**|只要 `Seq != Last + 1` 就报警。|维护 1 秒滑动窗口。统计窗口内的丢包率 (PLR)。仅当 `PLR > 阈值` 时报警。| |**灵敏度**|**极高**。偶发的单个丢包也会导致界面闪烁告警,造成“狼来了”效应。|**适中**。过滤掉偶发的网络毛刺,关注持续性的链路质量恶化。| |**适用性**|调试模式。|**生产环境标准解**。| ### 议题 2:时序异常处理 (Timing Anomaly) |**选项**|**A. 仅基于序列号 (Seq Only)**|**B. 序列号 + 时间戳双重校验 (Seq + Time) (推荐)**| |---|---|---| |**机制**|序列号递增即接收。|序列号递增 **且** `Timestamp > LastTimestamp`。| |**风险**|无法检测“服务器时钟回跳”或“重放攻击”。|**高健壮性**。防止因服务器端时钟故障导致的逻辑混乱。| --- ## 三、 基线确立与实施规范 为了构建一个“可诊断”的显控终端,我们确立 **B. 统计窗口平滑** + **B. 双重校验** 为基线。 ### 1. 诊断上下文状态机 (Diagnostic Context) 显控端必须为**每一个**检测到的 `station_id` 维护一个独立的诊断上下文: ```cpp struct StationDiagnosticContext { uint32_t station_id; // 序列跟踪 uint64_t last_seq_id = 0; uint64_t last_timestamp_us = 0; // 统计窗口 (1s) uint32_t expected_packets = 0; uint32_t lost_packets = 0; // 链路状态 bool connected = false; uint64_t last_seen_local_us = 0; // 用于检测静默/断连 }; ``` ### 2. 核心诊断逻辑基线 显控端收到 `TrackDataBatch` 后的标准处理流水线: - **步骤 1:源识别** - 读取 `station_id`。 - 在 Map 中查找对应的 `StationDiagnosticContext`。若无,则创建新上下文(视为新站点上线)。 - **步骤 2:时序完整性检查 (Sequencing)** - **乱序/重复**:`if (batch.seq <= ctx.last_seq)` -> **立即丢弃**。记录 `Out-of-Order` 计数。 - **丢包**:`if (batch.seq > ctx.last_seq + 1)` -> **判定为丢包**。 - 丢包数 `loss = batch.seq - ctx.last_seq - 1`。 - 更新统计:`ctx.lost_packets += loss`。 - **更新**:`ctx.last_seq = batch.seq`。 - **步骤 3:端到端延迟遥测 (Latency Telemetry)** - **计算**:`latency = Now() - batch.timestamp_us`。 - **诊断**: - 若 `latency > 200ms`(典型阈值):标记为 **"High Latency"**。 - 若 `latency < 0`:标记为 **"Clock Skew"**(时钟不同步警告)。 - **步骤 4:服务器健康感知 (Server Health)** - 读取 `throttle_level`。 - **可视化**: - `Level 0`:绿色(正常)。 - `Level 1`:黄色(轻微发热)。显控端右上角显示小图标提示。 - `Level 2`:红色(严重过热)。显控端弹出 Toast 提示“数据已降级”。 ### 3. 断连判定机制 (Dead Link Detection) - **机制**:显控端需运行一个独立的 1Hz 定时器,遍历所有 `StationDiagnosticContext`。 - **判据**:`if (Now() - ctx.last_seen_local_us > 2000ms)`。 - **动作**: - 将该 Station 标记为 **"Disconnected"**。 - 在态势图上灰置或清除该站点的所有目标。 - 触发声音告警。 --- ## 总结:2.4.3 基线图谱 |**诊断维度**|**字段来源**|**判定逻辑**|**显控端行为**| |---|---|---|---| |**丢包 (Loss)**|`batch_sequence_id`|`Current > Last + 1`|统计丢包率,不补发,仅告警。| |**乱序 (Reorder)**|`batch_sequence_id`|`Current <= Last`|**静默丢弃**,防止画面回跳。| |**延迟 (Latency)**|`timestamp_us`|`LocalTime - Timestamp`|超过阈值(如 200ms)提示“数据滞后”。| |**断连 (Dead)**|(本地接收时间)|`Silence > 2s`|标记站点离线,清空目标。| |**过热 (Thermal)**|`throttle_level`|`Level > 0`|UI 显性提示用户“服务器过热/数据降级”。| 下一步行动: 至此,我们已经完整定义了数据如何发(2.4.1/2.4.2)以及如何收(2.4.3)。2.4.4 热节流响应 在之前的讨论中已经涵盖(作为 Server 端行为),2.4.5 的核心也在本节的延迟遥测中定义了。 **建议**:我们可以结束 **2.4 外部目标数据分发协议** 的讨论,进入 **2.5 数据结构定义与序列化规范**(虽然我们在 2.4.2 中已经定义了 Proto,但可能还需要补充 C++ 内部结构体定义),或者直接进入 **第三章:异构计算架构与资源调度**。 鉴于我们在 2.4.2 中已经非常详细地定义了 `.proto`,且 `02_核心数据结构.md` 已经提供了 C++ 结构体定义,我建议**跳过 2.5**(除非您有特定结构体需要深究),直接进入 **第三章**,去解决最硬核的计算资源分配问题。 **提问**:您是否确认 **2.4.3 的多站独立诊断基线**?确认后我们是否直接进入 **第三章**?