Deterministic packet-level network simulator and TCP congestion-control lab for MoonBit
Dependencies
| 模块 | 内容 | 状态 |
|---|---|---|
| src/sim | 虚拟时间、确定性事件队列、可复现随机源 | 完成 |
| src/net | 数据包、有界队列(drop-tail / RED / CoDel)、链路(带宽/延迟/抖动/丢包) | 完成 |
| src/tcp | 连接状态机、三次握手、序号与累计确认、滑动窗口、乱序重组 | 完成 |
| src/tcp | RTO 估计(RFC 6298)、Karn 算法、超时重传与指数退避、NewReno 多丢包恢复、尾部丢包探测 | 完成 |
| src/tcp | 可插拔拥塞控制接口、Reno(RFC 5681/6928)、CUBIC(RFC 9438) | 完成 |
| src/json | 零依赖的 JSON 读写,供场景文件与报告使用 | 完成 |
| src/lab | 场景文件、运行、指标报告、对比与扫描、多流公平性 | 完成 |
| cmd/moonnet | 六个子命令:run / plot / compare / sweep / list / version | 完成 |
| examples/ | 两个用库写成的消费者程序(不含命令行):embed_tcp、rpc_retry | 完成 |
moon test # 运行全部测试
moon run cmd/moonnet -- list # 列出 scenarios 目录里的实验
moon run cmd/moonnet -- run scenarios/long-fat.json --cc cubic
moon run cmd/moonnet -- run scenarios/bufferbloat-shallow.json --cc reno --trace --json > trace.json
moon run cmd/moonnet -- plot trace.json > trace.svg
moon run cmd/moonnet -- compare scenarios/long-fat.json --cc reno,cubic
moon run cmd/moonnet -- sweep scenarios/small-buffers.json --field loss --from 0 --to 0.02 --steps 5
moon run cmd/moonnet -- sweep scenarios/bufferbloat.json --field queue_packets --from 16 --to 600 --steps 5 --cc reno,cubic --seeds 3
moon run cmd/moonnet -- run scenarios/fairness.json # 多条流抢一条链路
moon run cmd/moonnet -- run scenarios/bufferbloat.json --discipline codellet sim = @sim.Sim::new(seed) // 虚拟时钟 + 冻结的随机源
let pair = @tcp.LinkPair::new_with_cc( // 两个端点 + 两条链路
sim,
@tcp.TcpConfig::new(1000, 64000, 1000U),
@tcp.TcpConfig::new(1000, 64000, 5000U),
@net.LinkSpec::new("up", 10_000_000L, @sim.Time::from_ms(25L), @net.QueueSpec::packets(64)).with_loss(0.01),
@net.LinkSpec::new("down", 10_000_000L, @sim.Time::from_ms(25L), @net.QueueSpec::packets(64)).with_loss(0.01),
seed,
@tcp.cubic(1000),
)
pair.connect(sim)
pair.client.send(sim, Bytes::make(1_000_000, b'x'))
sim.step_until(() => pair.server.delivered_bytes() == 1_000_000) |> ignoremoon run examples/embed_tcp/main # 三个算法跑同一段传输
moon run examples/rpc_retry/main # 不同丢包率下,一次调用要几次重试moon run cmd/moonnet -- compare scenarios/small-buffers.json --cc none,renoscenario: small buffers (seed 9, 200000 bytes, 1 run each)
algorithm mean fastest slowest throughput retransmits timeouts
none 3908.214s 3908.214s 3908.214s 0.4 105 70
reno 662.277ms 662.277ms 662.277ms 2415.9 2 0scenario: long fat path (seed 9, 20000000 bytes, 1 run each)
algorithm mean fastest slowest throughput retransmits timeouts
reno 214.129s 214.129s 214.129s 747.2 425 27
cubic 318.218s 318.218s 318.218s 502.7 199 12algorithm mean fastest slowest throughput retransmits timeouts
reno 706.083s 214.129s 1312.194s 226.6 1177 112
cubic 218.618s 166.922s 318.218s 731.8 591 23moon run cmd/moonnet -- list
moon run cmd/moonnet -- run scenarios/long-fat.json --cc reno
moon run cmd/moonnet -- run scenarios/long-fat.json --cc cubic
moon run cmd/moonnet -- run scenarios/long-fat.json --json > report.json{
"name": "long fat path",
"seed": 9,
"payload_bytes": 20000000,
"algorithm": "reno",
"uplink": { "bandwidth_bps": 100000000, "delay_ms": 50, "loss": 0.01, "queue_packets": 2000 },
"client": { "mss": 1000, "receive_window": 2000000 }
}moon run cmd/moonnet -- compare scenarios/long-fat.json --cc reno,cubicscenario: long fat path (seed 9, 20000000 bytes, 1 run each)
algorithm mean fastest slowest throughput retransmits timeouts
reno 214.129s 214.129s 214.129s 747.2 425 27
cubic 318.218s 318.218s 318.218s 502.7 199 12
note: loss follows packet identity, so every row meets the same lost
packets on a given seed. Acknowledgments carry no identity and
fall back to transmission order, so their losses still differ.
In a lossy scenario a few sixty-second timeouts dominate the
total; more than one run is what makes the mean meaningful.moon run cmd/moonnet -- compare scenarios/long-fat.json --cc reno,cubic --seeds 4moon run cmd/moonnet -- sweep scenarios/small-buffers.json --field loss --from 0 --to 0.02 --steps 5 --cc reno,cubicscenario: small buffers, sweeping loss
loss reno kbit/s cubic kbit/s
0.0000 919.5 744.4
0.0100 597.2 601.7
0.0200 574.4 414.1
times:
loss reno cubic
0.0000 1.740s 2.149s
0.0100 2.678s 2.659s
0.0200 2.785s 3.863s"flows": [ { "algorithm": "reno", "count": 2 }, { "algorithm": "cubic", "count": 2 } ]moon run cmd/moonnet -- run scenarios/fairness.jsonscenario: fairness: two reno against two cubic (seed 9, 4 flows sharing one path, 10.000s window)
flow algorithm delivered share % kbit/s retransmits timeouts
flow 0 reno 3789000 31.0 3031.2 0 0
flow 1 reno 1062987 8.7 850.3 62 0
flow 2 cubic 3777000 30.9 3021.6 0 0
flow 3 cubic 3564000 29.2 2851.2 4 0
total: 12192987 bytes
fairness: 0.8754 (Jain index over the shares above)
uplink: 65 dropped at the queue, 1 lost on the wire"uplink": { "bandwidth_bps": 5000000, "delay_ms": 10, "queue_packets": 600, "discipline": "codel" }moon run cmd/moonnet -- run scenarios/bufferbloat.json # drop-tail
moon run cmd/moonnet -- run scenarios/bufferbloat.json --discipline codel
moon run cmd/moonnet -- run scenarios/bufferbloat.json --discipline red
moon run cmd/moonnet -- run scenarios/bufferbloat-shallow.json # 同一条路径,缓冲区 64 个包| 队列策略 | 缓冲区 | 传输耗时 | 吞吐 | 最坏排队延迟 | 队列丢弃 | 超时 |
|---|---|---|---|---|---|---|
| drop-tail | 600 包 | 16.610s | 1444.9 kbit/s | 978.7 ms | 614 次(全部在队尾) | 0 |
| CoDel | 600 包 | 5.044s | 4757.7 kbit/s | 226.4 ms | 34 次(全部提前) | 0 |
| RED | 600 包 | 19273.903s | 1.2 kbit/s | 978.7 ms | 329 次(192 次提前) | 326 |
| drop-tail | 64 包 | 7.403s | 3241.7 kbit/s | 104.4 ms | 134 次(全部在队尾) | 0 |
src/sim/ 虚拟时间、事件内核、随机源
src/net/ 数据包、队列(含队列管理策略)、链路
src/tcp/ 连接状态机、重传与恢复、拥塞控制
src/json/ 零依赖 JSON 读写
src/lab/ 场景、报告、对比与扫描、多流公平性
cmd/moonnet/ 命令行入口
examples/ 用库写的两个程序(下游的样子)
scenarios/ 可编辑的实验文件
docs/ 设计说明、路线图、生态定位、验证方式、接口契约、申报书| moonsim | moonnet-lab | |
|---|---|---|
| 时间单位 | 抽象 tick | 皮秒整数,可手算校验(1500 字节 @ 10 Mbps = 1.2 毫秒) |
| 网络模型 | 消息延迟区间 + 丢弃百分比 | 带宽、传播延迟、抖动、按字节与包数限制的队列 |
| 队列 | 排队论模型(顾客、服务时间、到达间隔) | 有界缓冲区 + 队列管理策略(drop-tail / RED / CoDel),排队延迟是可测量 |
| 协议内容 | 通用事件类型(消息/任务/定时器/状态转移/外部调用) | TCP 状态机、RTO 估计(RFC 6298)、快速重传与多丢包恢复 |
| 算法内容 | 重试、熔断、限流、负载均衡等可靠性模式 | Reno(RFC 5681/6928)、CUBIC(RFC 9438)等拥塞控制算法 |
| 用途 | 让服务里偶发的失败可复现,进 CI 回归 | 回答"这条路径上哪个算法更好、缓冲区该多大" |
Install
Download zipDeterministic packet-level network simulator and TCP congestion-control lab for MoonBit
Dependencies