网络上的数据,对电脑来说是一串串 0 和 1,对人类来说基本是天书。
但如果我们能把天书翻译成"谁、在什么时间、跟谁、传了多少数据",很多问题就变得清晰了。
chensuiyi/packet 是 MoonBit 语言的一个数据解析模块,专门负责这个翻译工作。
它输入一段原始网络数据,输出一份人类能读懂的"通信档案"。
一段网络数据,里面藏着什么?
网络数据虽然看起来乱,但其实是有固定格式的,一层套一层。
最外面一层,记录了收发双方的硬件地址,相当于快递单上的寄件人和收件人。
中间一层,记录了双方的 IP 地址,相当于城市和街道。
最里面一层,记录了双方的端口号,相当于具体到几号房间。
packet 模块做的事,就是把这几层一层层拆开,把里面的关键信息提取出来。
提取出来的"通信档案"长什么样?
核心是一份五元组信息,五个要素:
- 源 IP:数据从哪个地址发出
- 源端口:数据从哪个程序发出
- 目标 IP:数据发往哪个地址
- 目标端口:数据发往哪个程序
- 协议类型:用的什么传输方式
五个要素合在一起,就能唯一确定一条通信连接。
就像快递单上的寄件人、收件人、物品类型,合在一起能唯一确定一单快递。
如何下载安装?
MoonBit 是一门新的编程语言,语法风格类似 Rust 但更简洁,编译成 WebAssembly 后体积小、速度快,主要面向云原生场景。
语言文档:docs.moonbitlang.com
访问官方,MoonBit 工具链在 Windows 上用 PowerShell 一条命令安装。
安装完成后验证一下:
moon --version
然后新建一个项目,引入解析模块:
moon new packet-demo
cd packet-demo
moon add chensuiyi/packet
一个完整示例
调用一次解析函数,传入一段原始网络数据和抓包时间,就能拿到结果:
// data:一段原始网络数据(字节)
// ts_sec、ts_usec:抓包时间
// local_ips:本机 IP 列表(用于判断数据方向)
match @packet.parse(data, ts_sec, ts_usec, local_ips) {
Some(p) => println(p.tuple.to_string())
None => println("解析失败")
}
实际解析一段"以太网 + IPv4 + TCP"三层结构的数据,输出是:
192.168.1.1:443 -> 192.168.1.2:1234 tcp
意思是:从 192.168.1.1 的 443 端口,通过 TCP 方式,发往 192.168.1.2 的 1234 端口。
一段看不懂的十六进制数据,就这样变成了人能读懂的通信档案。
解析成功时,还能拿到这些信息:
| 信息 | 说明 |
|---|---|
| 五元组 | 谁、通过什么方式、跟谁通信 |
| 方向 | 数据是发出的、收到的,还是本机内部的 |
| 载荷长度 | 真正传输的数据有多大 |
| 总长度 | 整个数据包有多大 |
能做到什么效果?
要统计电脑流量的去向,把每个数据包解析成五元组,再按连接汇总,就能得出每条通信连接传了多少数据。
要做网络可视化展示,解析出每一条连接,画成图表或动画,就能直观呈现网络的实时状态。
要排查某个程序连不上服务器的问题,解析数据包查看连接目标、端口和方向,就能定位问题所在。
这个模块有什么特点?
- 纯 MoonBit 实现,不依赖任何外部库,任何环境都能跑。
- 支持 IPv4 和 IPv6 两种地址格式。
- 支持 TCP、UDP、ICMP 等常见传输方式。
- 遇到不完整或无法识别的数据,直接跳过,不会让程序崩溃。
- 解析逻辑和数据抓取完全分离,可以独立测试、独立复用。
什么场景下会用到它?
需要看懂网络数据的程序都可以使用:
- 网络监控工具
- 流量统计工具
- 网络调试工具
- 安全分析工具