# 与已有生态的关系

申报书里这一节只留结论，论证过程和数据放在这里。

## 一、与 moonsim：研究对象不同，不是功能多少不同

先把重叠说清楚，因为"已被覆盖"这个判断正是从这里来的：两者都是 MoonBit 里的确定性仿真，都提供虚拟时间、种子、扫描与多种子矩阵。

| | moonsim | moonnet-lab |
| --- | --- | --- |
| 研究对象 | 服务的可靠性逻辑（消息、任务、状态机、外部调用） | 网络与传输协议的行为 |
| 网络模型 | 抽象消息层：延迟区间 + 丢弃百分比，单位是 tick | 链路：带宽、传播延迟、抖动、按字节与包数限制的队列 |
| 队列 | 排队论模型（顾客、服务时间、到达间隔） | 有界缓冲区 + 队列管理策略（drop-tail / RED / CoDel），排队延迟是可测量的量 |
| 协议 | 无 | TCP 状态机、RFC 6298 的 RTO 估计、快速重传、多丢包恢复 |
| 算法 | 重试、熔断、限流、负载均衡等可靠性模式 | Reno（RFC 5681/6928）、CUBIC（RFC 9438）等拥塞控制 |
| 时间单位 | tick（抽象） | 皮秒（可手算校验：1500 字节 @ 10 Mbps = 1.2 毫秒） |
| 用途 | 让服务里偶发的失败可复现，进 CI 回归 | 回答"这条路径上哪个算法更好、缓冲区该多大、队列该怎么管" |

### 判断标准：差异改变了能回答的问题，还是只多了一个开关

moonsim 的模型里没有"拥塞窗口"，也没有"队头等待时间"。下面三组输出它结构上无法产出，不是因为它做得不够好，是因为这两个量在它的抽象里不存在：

```text
$ moon run cmd/moonnet -- compare scenarios/long-fat.json --cc reno,cubic --seeds 3
reno   mean  706.083s   timeouts 112
cubic  mean  218.618s   timeouts  23

$ moon run cmd/moonnet -- run scenarios/fairness.json
flow 0 reno 31.0% | flow 1 reno 8.7% | flow 2 cubic 30.9% | flow 3 cubic 29.2%
Jain index 0.8754，聚合 9.75 Mbps（10 Mbps 链路的 97%）

$ moon run cmd/moonnet -- run scenarios/bufferbloat.json              # drop-tail，600 包缓冲区
elapsed 16.610s   throughput 1444.9 kbit/s   worst queueing delay 978.7 ms
$ moon run cmd/moonnet -- run scenarios/bufferbloat.json --discipline codel
elapsed  5.044s   throughput 4757.7 kbit/s   worst queueing delay 226.4 ms
$ moon run cmd/moonnet -- run scenarios/bufferbloat-shallow.json      # 同一条路径，64 包缓冲区
elapsed  7.403s   throughput 3241.7 kbit/s   worst queueing delay 104.4 ms
```

第三组最说明问题：**同一条 5 Mbps 链路、同一份 3 MB 数据、同一个拥塞控制，只把缓冲区深度从 64 个包加到 600 个包，传输慢 2.2 倍、排队延迟涨 9.4 倍；把"满了才丢"换成"队头等待超过 5 毫秒就提前丢"，传输又快回 3.3 倍。** 这里起作用的是一个回路：缓冲区深度改变排队延迟，排队延迟改变往返时间，往返时间改变拥塞窗口的收敛速度，窗口再决定缓冲区里堆多少。moonsim 的抽象里这个回路不存在。

同一组实验还跑出一个没预期的结果：RED 在这条路径上把连接锁死（3 MB 数据 19273.9 秒、326 次超时）。原因是它的判定量是"到达时更新的平均占用"，单条流停止发包后这个平均值降不下来，于是只有 60 秒一次的定时器重传在推进，每次都被拒绝；换成 `--cc reno` 同样复现（17128.9 秒），所以是策略的性质而不是算法的性质。这不是设计出来的结论，是实验台上跑出来的——它的价值在于说明这台仪器能产出文献之外的新数据。

### 为什么不作为补丁贡献给 moonsim

两个技术原因，都写在实测里而不是客套话里：

1. **时间粒度不兼容。** moonsim 的核心单位是 tick，而链路串行化要求整数时间精确到皮秒级（1500 字节的帧在 10 Mbps 链路上占 1.2 毫秒，这个数要能被断言）。把 tick 换成皮秒会改变它的核心语义与全部既有结果。
2. **范围不同。** moonsim 明确声明"专注模型测试；真实网络压测和生产基础设施运行由对应工具负责"，它 0.3.x 的稳定性承诺也不适合容纳一个仍在演进的协议模型。

如果维护者认为 `models/tcp` 值得做，那是一条合理的替代路径，但它会是另一个更小的东西：一个模型文件，而不是一台实验台（含场景文件、受控丢包、多流公平性、队列策略与报告）。

**更要紧的一句**：如果生态只能留一个，应该留 moonsim，把本项目里最有价值的部分——TCP 与拥塞控制的模型——作为它的一个领域模型上游。这也是我们愿意接受的结果。

## 二、与 Mininet、ns-3 的关系

| | Mininet | ns-3 | moonnet-lab |
| --- | --- | --- | --- |
| 原理 | 真实 Linux 内核协议栈 + namespace + tc/netem | 离散事件仿真（C++） | 离散事件仿真（MoonBit） |
| 保真度 | 最高（真实协议栈） | 中 | 中（协议按 RFC 实现） |
| 可复现 | 差（真实时钟与内核调度） | 好 | 好（事件序、随机数、丢包位置全部固定） |
| 运行环境 | Linux + root，或虚拟机/容器 | 独立工程 | 任意平台，可嵌入 `moon test` 与 CI |
| 换算法 | 需要写内核模块 | 需要改 C++ 并重编 | 实现一个 7 方法的接口 |

Mininet 是保真度最高的选择：如果目标是"验证真实协议栈在真实硬件上的行为"，没有理由重做它。但它的三个性质决定了它承担不了本项目的用途——不可复现、需要 root 与 Linux、无法嵌入一个语言的测试套件。**本项目的定位是"语言生态内可嵌入、可复现的实验台"，不是 Mininet 的替代品**；就像 ns-3 也没有替代 Mininet，两者服务不同的问题。

## 三、立项前的生态扫描与项目意义

立项前扫描了 mooncakes.io 上全部 2491 个包，拥塞控制、丢包恢复相关关键词的命中都是同名误匹配。生态里有链接库、有协议头解析，但没有可以验证协议**行为**的环境。

1. **生态空白**：见上。填补的是一个"能验证协议行为"的位置，而不是又一个工具库。
2. **可复现本身是基础设施**：它不是产品，而是让别人（以及 AI 代理）能对协议做实验的地基——确定性加上机器可读报告，意味着实验可以被复算、被推翻、被固化进回归测试。
3. **教学价值**：TCP 拥塞控制是最经典也最难讲清的主题之一。把它变成能跑的代码、能改的参数、能对比的两种算法，是这个项目最直接的用途。
