go-ping是Go语言中实现ICMP ping功能的成熟库,封装了raw socket、超时控制与统计逻辑,支持跨平台(Windows需管理员权限),提供Count、Timeout等可配置参数及Statistics结果含丢包率和RTT指标。

Go 里没有内置 ping,得自己发 ICMP 包
标准 net 包不支持 ICMP,os/exec 调 ping 命令又不可控、难解析、跨平台行为不一致。真要测丢包率和延迟,必须用 raw socket 构造 ICMP Echo Request。Linux/macOS 需要 root 权限,Windows 上要用 winpcap 或 golang.org/x/net/icmp(它底层仍依赖系统权限)。
推荐直接用成熟库:github.com/sparrc/go-ping。它封装了 raw socket、超时控制、统计逻辑,且兼容主流系统(Windows 需管理员权限运行)。
- 不用自己处理 IP 头校验和、ICMP 校验和 ——
go-ping全包了 - 支持设置
Count、Timeout、Interval,能拿到每次响应的Rtt和是否超时 - 返回的
*ping.Statistics包含PacketsSent、PacketsRecv、AvgRtt、MaxRtt等字段,丢包率 =(PacketsSent - PacketsRecv) / PacketsSent * 100
用 go-ping 测延迟和丢包的最小可行代码
别写一堆循环和计时器,go-ping 的 Run() 方法会自动发包、收包、统计。关键参数就三个:目标地址、发包数、超时时间。
package main
<p>import (
"fmt"
"time"
"github.com/sparrc/go-ping"
)</p><p>func main() {
pinger, err := ping.NewPinger("8.8.8.8")
if err != nil {
panic(err)
}
pinger.Count = 10 // 发 10 个包
pinger.Timeout = 5 <em> time.Second
pinger.Interval = 1 </em> time.Second</p><pre class="brush:php;toolbar:false;">err = pinger.Run()
if err != nil {
panic(err)
}
stats := pinger.Statistics()
loss := float64(stats.PacketsSent-stats.PacketsRecv) / float64(stats.PacketsSent) * 100
fmt.Printf("Loss: %.1f%%, Avg RTT: %v\n", loss, stats.AvgRtt)}
注意:pinger.Run() 是阻塞调用,别在 goroutine 里漏掉 defer pinger.Stop()(虽然 Run() 内部会 stop,但手动调更稳妥)。
为什么不能只看平均延迟?RTT 分布更重要
丢包率低但延迟抖动大,对实时音视频或游戏就是灾难。go-ping 的 Statistics() 不提供完整 RTT 列表,得自己 hook OnRecv 回调:
- 设置
pinger.OnRecv = func(pkt *ping.Packet),每次收到回复就记录pkt.Rtt - 配合
OnFinish汇总,就能算出 min/max/stddev,甚至画分布直方图 - 别依赖
AvgRtt——它只是算术平均,被个别长尾延迟拉高,而MedianRtt更有参考价值(需自行计算)
另外,ICMP 包可能被中间设备限速或过滤,单次测试结果波动大。生产环境建议至少跑 30 秒以上,且避开高峰期对比基线。
Windows 上跑不起来?权限和防火墙是两大拦路虎
Windows 默认禁止非管理员进程创建 raw socket。错误通常是:failed to listen on raw socket: operation not permitted 或 bind: permission denied。
- 必须以管理员身份运行程序(右键 → “以管理员身份运行”)
- Windows Defender 防火墙可能拦截 ICMP 回复,临时关闭或添加入站规则(协议类型选“ICMPv4”)
- 某些企业网络禁用 ICMP,这时
go-ping会全丢包,但net.Dial("tcp", "8.8.8.8:80")能通 —— 说明不是你代码问题,是网络策略
如果真不能用 ICMP,只能退到 TCP 层测连通性(比如连 80/443 端口测 handshake 时间),但那不算“ping”,也得不到真实丢包率。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











