ping 命令与基于 Go 的简单实现
在日常工作中,我们经常需要确认与远程主机的连接状态,而 ping 就是一种常用的网络工具,用于测试与目标主机之间的网络连接。它通过发送 ICMP 回显请求报文,并等待目标主机返回 ICMP 回显应答报文来判断连接是否正常,以及网络延迟和丢包情况。
步骤
- 发送 ICMP 回显请求消息:
- 操作系统构建一个 ICMP 回显请求消息数据包。
- 该数据包包含:
- ICMP Type (8,表示 Echo request)
- ICMP Code (0)
- 校验和 (确保数据完整性)
- 标识符 (用于匹配请求和回复)
- 序列号 (用于跟踪发送的请求)
- 可选的数据负载 (通常是一串字符)
- 数据包被封装到 IP 数据报中,并发送到目标主机。
- 目标主机接收 ICMP 回显请求消息:
- 目标主机网络接口接收到 IP 数据报。
- IP 数据报被解封装,提取出 ICMP 回显请求消息。
- 目标主机操作系统识别 ICMP 类型和代码。
- 目标主机发送 ICMP 回显回复消息:
- 目标主机操作系统构建一个 ICMP 回显回复消息数据包。
- 该数据包包含:
- ICMP Type (0,表示 Echo reply)
- ICMP Code (0)
- 校验和
- 标识符 (与请求消息中的相同)
- 序列号 (与请求消息中的相同)
- 请求消息中的数据负载
- 数据包被封装到 IP 数据报中,并发送回源主机。
- 源主机接收 ICMP 回显回复消息:
- 源主机网络接口接收到 IP 数据报。
- IP 数据报被解封装,提取出 ICMP 回显回复消息。
- 操作系统计算往返时间 (RTT)。
基于 Go 的 ping 命令简单实现
这里使用了 golang.org/x/net/icmp 扩展库来实现一个简单的 ping 功能:
1 | func Ping(addr string) error { |
留意一点区别:在 Windows 下编译后生成的程序可以直接运行,但是在 Linux 下编译生成的程序需要 root 权限,这跟不同操作系统的原始套接字操作权限相关。