ping 命令通过发送 ICMP(Internet Control Message Protocol)回显请求包到目标主机,并等待 ICMP 回显应答来测试网络连接。它是网络故障排除中最基础且重要的工具。
ping [选项] 目标主机
目标主机格式:
ping example.comping 8.8.8.8ping 2001:4860:4860::8888| 选项 | 说明 |
|---|---|
-c 次数 |
指定发送数据包的次数 |
-i 间隔 |
设置发送数据包的间隔时间(秒) |
-s 大小 |
指定发送数据包的大小(字节) |
-t TTL |
设置数据包的 TTL(Time To Live)值 |
-w 超时 |
设置命令执行的超时时间(秒) |
-W 等待时间 |
等待每个回复的超时时间(秒) |
-q |
安静模式,只显示统计信息 |
-v |
详细输出模式 |
-4 |
强制使用 IPv4 |
-6 |
强制使用 IPv6 |
-I 接口 |
指定使用的网络接口 |
-n |
不进行域名解析,直接显示 IP 地址 |
# 测试到Google DNS服务器的连通性
ping 8.8.8.8
# 使用域名测试
ping google.com
# 输出示例:
# PING google.com (142.250.74.46) 56(84) bytes of data.
# 64 bytes from 142.250.74.46: icmp_seq=1 ttl=118 time=10.8 ms
# 64 bytes from 142.250.74.46: icmp_seq=2 ttl=118 time=11.2 ms
# 64 bytes from 142.250.74.46: icmp_seq=3 ttl=118 time=10.5 ms
# 发送5个ping包后停止
ping -c 5 8.8.8.8
# 输出示例:
# PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
# 64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=11.3 ms
# 64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=10.9 ms
# 64 bytes from 8.8.8.8: icmp_seq=3 ttl=118 time=11.1 ms
# 64 bytes from 8.8.8.8: icmp_seq=4 ttl=118 time=10.8 ms
# 64 bytes from 8.8.8.8: icmp_seq=5 ttl=118 time=11.0 ms
# --- 8.8.8.8 ping statistics ---
# 5 packets transmitted, 5 received, 0% packet loss, time 4005ms
# rtt min/avg/max/mdev = 10.832/11.022/11.300/0.173 ms
# 发送1000字节的数据包
ping -s 1000 8.8.8.8
# 发送1500字节的数据包(测试标准MTU)
ping -s 1500 8.8.8.8
# 发送2000字节的数据包(测试是否支持分片)
ping -s 2000 8.8.8.8
# 快速发送ping包(间隔0.2秒)
ping -i 0.2 -c 10 8.8.8.8
# 每秒发送一个包
ping -i 1 google.com
# 安静模式,只显示统计信息
ping -q -c 20 8.8.8.8
# 输出示例:
# PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
#
# --- 8.8.8.8 ping statistics ---
# 20 packets transmitted, 20 received, 0% packet loss, time 19021ms
# rtt min/avg/max/mdev = 10.815/11.089/11.416/0.179 ms
# 设置等待回复的超时时间为2秒
ping -W 2 8.8.8.8
# 设置整个ping命令的超时时间为10秒
ping -w 10 8.8.8.8
# 通过eth0接口发送ping请求
ping -I eth0 8.8.8.8
# 通过wlan0接口发送ping请求
ping -I wlan0 8.8.8.8
使用ping进行基本网络连通性测试:
# 1. 测试到目标主机的连通性
ping google.com
# 输出示例:
# PING google.com (142.250.189.206) 56(84) bytes of data.
# 64 bytes from 142.250.189.206: icmp_seq=1 ttl=115 time=12.3 ms
# 64 bytes from 142.250.189.206: icmp_seq=2 ttl=115 time=11.8 ms
# 64 bytes from 142.250.189.206: icmp_seq=3 ttl=115 time=12.1 ms
# ^C
# --- google.com ping statistics ---
# 3 packets transmitted, 3 received, 0% packet loss, time 2004ms
# rtt min/avg/max/mdev = 11.832/12.075/12.312/0.200 ms
# 2. 发送指定数量的数据包
ping -c 5 8.8.8.8
# 发送5个数据包后自动停止
# 3. 设置发送间隔
ping -i 2 192.168.1.1
# 每2秒发送一个数据包(默认是1秒)
# 4. 设置数据包大小
ping -s 1000 example.com
# 发送1000字节的数据包(包括28字节头部)
# 5. 设置超时时间
ping -W 3 10.0.0.1
# 等待回复的超时时间为3秒
# 6. 设置总运行时间
ping -w 10 google.com
# 总共运行10秒,无论发送了多少数据包
# 7. 只显示数字地址
ping -n 8.8.8.8
# 不解析主机名,直接显示IP地址
# 8. 安静模式
ping -q -c 10 google.com
# 只显示开始和结束统计,不显示每个数据包的详情
# 9. 详细模式
ping -v google.com
# 显示更多详细信息
# 10. 强制使用IPv4
ping -4 google.com
# 即使有IPv6地址,也使用IPv4
# 11. 强制使用IPv6
ping -6 ipv6.google.com
# 使用IPv6地址
# 12. 指定网络接口
ping -I eth0 8.8.8.8
# 通过eth0接口发送数据包
# 13. 设置TTL(生存时间)
ping -t 30 google.com
# 设置TTL为30跳
# 14. 显示时间戳
ping -D google.com
# 在每个数据包前打印UNIX时间戳
# 15. 记录路由
ping -R google.com
# 记录并显示路由(最多9个跃点)
# 16. 测试本地回环
ping 127.0.0.1
# 测试本地网络栈是否正常
# 17. 测试网关连通性
# 先查看网关IP
ip route | grep default
# 通常类似:default via 192.168.1.1
ping 192.168.1.1
# 测试到网关的连通性
# 18. 测试DNS服务器
# 查看DNS服务器
cat /etc/resolv.conf
# 测试DNS服务器连通性
ping 8.8.8.8
ping 1.1.1.1
# 19. 测试多个目标
for host in 8.8.8.8 1.1.1.1 9.9.9.9; do
echo "测试 $host:"
ping -c 2 $host
echo ""
done
# 20. 在脚本中检查连通性
check_connectivity() {
if ping -c 1 -W 1 "$1" &> /dev/null; then
echo "$1: 可达"
return 0
else
echo "$1: 不可达"
return 1
fi
}
check_connectivity google.com
check_connectivity 8.8.8.8
# 21. 测量网络质量
ping -c 20 -i 0.2 8.8.8.8
# 发送20个数据包,间隔0.2秒
# 查看丢包率和延迟统计
# 22. 检测间歇性网络问题
# 持续ping监控
ping 8.8.8.8
# 按Ctrl+C停止
# 观察是否有丢包或延迟突增
# 23. 测试MTU(最大传输单元)
# 发送不同大小的数据包测试
for size in 1472 1473 1500 1501; do
echo "测试 $size 字节:"
ping -c 2 -s $size -M do 8.8.8.8
echo ""
done
# 24. 使用ping进行简单端口扫描
# 注意:这不是ping的标准用法
for i in {1..254}; do
ping -c 1 -W 1 192.168.1.$i &> /dev/null && echo "192.168.1.$i 活跃"
done
# 25. 测试网络带宽(近似)
# 这不是精确的带宽测试,但可以近似
ping -f -c 1000 -s 1472 8.8.8.8
# 洪水ping,发送大量数据包
# 警告:可能对网络造成压力
# 26. 在后台运行ping
ping 8.8.8.8 > ping.log 2>&1 &
# 后台运行,输出到文件
# 查看进程
jobs
# 停止后台ping
kill %1
# 27. 使用ping测试VPN连通性
# 连接VPN后
ping 10.8.0.1
# 测试VPN服务器的内部IP
# 28. 测试多播
ping -I eth0 224.0.0.1
# 测试多播地址(本地子网所有主机)
# 29. 使用ping进行网络发现
# 结合arp命令
ping -c 2 -b 192.168.1.255
arp -a
# 查看哪些主机响应了广播ping
# 30. 创建ping监控脚本
#!/bin/bash
# ping监控脚本
TARGET="8.8.8.8"
LOG_FILE="/var/log/ping-monitor.log"
while true; do
if ! ping -c 1 -W 1 "$TARGET" &> /dev/null; then
echo "$(date): 网络中断" >> "$LOG_FILE"
fi
sleep 5
done
使用ping进行网络故障排查和诊断:
#!/bin/bash
# 网络故障排查和诊断脚本
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 1. 网络连通性诊断
network_diagnosis() {
local target=${1:-"8.8.8.8"}
echo -e "${BLUE}=== 网络连通性诊断: $target ===${NC}"
echo ""
# 测试本地回环
echo -e "${YELLOW}1. 测试本地网络栈:${NC}"
if ping -c 2 -W 1 127.0.0.1 &> /dev/null; then
echo -e "${GREEN}✓ 本地网络栈正常${NC}"
else
echo -e "${RED}✗ 本地网络栈故障${NC}"
fi
# 测试本地IP
echo -e "\n${YELLOW}2. 测试本地IP地址:${NC}"
local_ip=$(hostname -I | awk '{print $1}')
if [ -n "$local_ip" ]; then
if ping -c 2 -W 1 "$local_ip" &> /dev/null; then
echo -e "${GREEN}✓ 本地IP ($local_ip) 可达${NC}"
else
echo -e "${RED}✗ 本地IP不可达${NC}"
fi
fi
# 测试网关
echo -e "\n${YELLOW}3. 测试默认网关:${NC}"
gateway=$(ip route | grep default | awk '{print $3}' | head -1)
if [ -n "$gateway" ]; then
if ping -c 2 -W 1 "$gateway" &> /dev/null; then
echo -e "${GREEN}✓ 网关 ($gateway) 可达${NC}"
else
echo -e "${RED}✗ 网关不可达${NC}"
fi
fi
# 测试DNS服务器
echo -e "\n${YELLOW}4. 测试DNS服务器:${NC}"
if grep -q "nameserver" /etc/resolv.conf; then
dns_server=$(grep "nameserver" /etc/resolv.conf | head -1 | awk '{print $2}')
if [ -n "$dns_server" ]; then
if ping -c 2 -W 1 "$dns_server" &> /dev/null; then
echo -e "${GREEN}✓ DNS服务器 ($dns_server) 可达${NC}"
else
echo -e "${RED}✗ DNS服务器不可达${NC}"
fi
fi
fi
# 测试目标主机
echo -e "\n${YELLOW}5. 测试目标主机 ($target):${NC}"
if ping -c 4 -W 2 "$target" &> /dev/null; then
# 获取详细统计
stats=$(ping -c 4 -W 2 "$target" | tail -2)
echo -e "${GREEN}✓ 目标主机可达${NC}"
echo "$stats"
else
echo -e "${RED}✗ 目标主机不可达${NC}"
fi
}
# 2. 网络质量测试
network_quality_test() {
local target=${1:-"8.8.8.8"}
local count=${2:-20}
echo -e "${BLUE}=== 网络质量测试: $target ===${NC}"
echo "发送 $count 个数据包进行测试..."
echo ""
# 执行ping测试
ping_result=$(ping -c "$count" -i 0.2 -W 1 "$target" 2>/dev/null)
if [ $? -eq 0 ]; then
# 解析结果
packet_loss=$(echo "$ping_result" | grep "packet loss" | awk '{print $6}' | cut -d'%' -f1)
rtt_stats=$(echo "$ping_result" | grep "rtt" | awk -F'=' '{print $2}')
echo -e "${YELLOW}测试结果:${NC}"
echo "目标: $target"
echo "数据包数量: $count"
echo ""
# 丢包率分析
echo -e "${YELLOW}丢包率分析:${NC}"
if [ -z "$packet_loss" ] || [ "$packet_loss" = "0" ]; then
echo -e "${GREEN}✓ 丢包率: 0% (优秀)${NC}"
elif [ "$packet_loss" -lt 5 ]; then
echo -e "${GREEN}✓ 丢包率: ${packet_loss}% (良好)${NC}"
elif [ "$packet_loss" -lt 20 ]; then
echo -e "${YELLOW}⚠ 丢包率: ${packet_loss}% (一般)${NC}"
else
echo -e "${RED}✗ 丢包率: ${packet_loss}% (差)${NC}"
fi
# 延迟分析
if [ -n "$rtt_stats" ]; then
echo -e "\n${YELLOW}延迟分析 (RTT):${NC}"
min_rtt=$(echo "$rtt_stats" | awk -F'/' '{print $1}')
avg_rtt=$(echo "$rtt_stats" | awk -F'/' '{print $2}')
max_rtt=$(echo "$rtt_stats" | awk -F'/' '{print $3}')
echo "最小延迟: ${min_rtt}ms"
echo "平均延迟: ${avg_rtt}ms"
echo "最大延迟: ${max_rtt}ms"
# 延迟评价
if (( $(echo "$avg_rtt < 50" | bc -l 2>/dev/null) )); then
echo -e "${GREEN}✓ 延迟: 优秀${NC}"
elif (( $(echo "$avg_rtt < 100" | bc -l 2>/dev/null) )); then
echo -e "${GREEN}✓ 延迟: 良好${NC}"
elif (( $(echo "$avg_rtt < 200" | bc -l 2>/dev/null) )); then
echo -e "${YELLOW}⚠ 延迟: 一般${NC}"
else
echo -e "${RED}✗ 延迟: 差${NC}"
fi
# 延迟抖动
mdev=$(echo "$rtt_stats" | awk -F'/' '{print $4}')
echo "延迟抖动: ${mdev}ms"
if (( $(echo "$mdev < 10" | bc -l 2>/dev/null) )); then
echo -e "${GREEN}✓ 网络稳定性: 优秀${NC}"
elif (( $(echo "$mdev < 30" | bc -l 2>/dev/null) )); then
echo -e "${GREEN}✓ 网络稳定性: 良好${NC}"
elif (( $(echo "$mdev < 50" | bc -l 2>/dev/null) )); then
echo -e "${YELLOW}⚠ 网络稳定性: 一般${NC}"
else
echo -e "${RED}✗ 网络稳定性: 差${NC}"
fi
fi
else
echo -e "${RED}测试失败: 无法连接到目标主机${NC}"
fi
# 生成报告
echo -e "\n${YELLOW}网络质量评级:${NC}"
if [ "$packet_loss" = "0" ] && (( $(echo "$avg_rtt < 50" | bc -l 2>/dev/null) )); then
echo -e "${GREEN}★★★★★ 优秀${NC}"
elif [ "$packet_loss" -lt 5 ] && (( $(echo "$avg_rtt < 100" | bc -l 2>/dev/null) )); then
echo -e "${GREEN}★★★★ 良好${NC}"
elif [ "$packet_loss" -lt 10 ] && (( $(echo "$avg_rtt < 200" | bc -l 2>/dev/null) )); then
echo -e "${YELLOW}★★★ 一般${NC}"
elif [ "$packet_loss" -lt 20 ] && (( $(echo "$avg_rtt < 300" | bc -l 2>/dev/null) )); then
echo -e "${YELLOW}★★ 较差${NC}"
else
echo -e "${RED}★ 差${NC}"
fi
}
# 3. 路径MTU发现
path_mtu_discovery() {
local target=${1:-"8.8.8.8"}
echo -e "${BLUE}=== 路径MTU发现: $target ===${NC}"
echo ""
# 常见的MTU值
mtu_values=(576 1280 1450 1472 1492 1500 9000)
echo -e "${YELLOW}测试不同MTU值:${NC}"
for mtu in "${mtu_values[@]}"; do
# 计算有效载荷大小(减去28字节头部)
payload=$((mtu - 28))
echo -n "测试 MTU $mtu ($payload 字节有效载荷): "
if ping -c 2 -s $payload -M do "$target" &> /dev/null; then
echo -e "${GREEN}✓ 成功${NC}"
else
echo -e "${RED}✗ 失败${NC}"
break
fi
done
# 使用ping自动发现MTU
echo -e "\n${YELLOW}使用ping自动发现MTU:${NC}"
ping -c 1 -s 1472 -M do "$target" 2>&1 | grep -i "frag needed"
}
# 4. 网络延迟故障排查
latency_troubleshooting() {
local target=${1:-"8.8.8.8"}
echo -e "${BLUE}=== 网络延迟故障排查 ===${NC}"
echo ""
# 测试不同大小的数据包
echo -e "${YELLOW}1. 测试不同数据包大小的延迟:${NC}"
echo "大小(字节) | 平均延迟(ms)"
echo "---------------------"
for size in 64 128 256 512 1024 1472; do
result=$(ping -c 3 -s $size -W 1 "$target" 2>/dev/null | grep "rtt" | awk -F'/' '{print $2}')
if [ -n "$result" ]; then
printf "%-10s | %s\n" "$size" "$result"
else
printf "%-10s | %s\n" "$size" "超时"
fi
done
# 测试不同TTL
echo -e "\n${YELLOW}2. 测试TTL对延迟的影响:${NC}"
for ttl in 1 16 32 64 128 255; do
result=$(ping -c 2 -t $ttl -W 1 "$target" 2>/dev/null | grep "time=" | head -1 | awk -F'=' '{print $4}' | awk '{print $1}')
if [ -n "$result" ]; then
echo "TTL $ttl: $result ms"
fi
done
# 测试不同间隔
echo -e "\n${YELLOW}3. 测试发送间隔对延迟的影响:${NC}"
for interval in 0.1 0.5 1 2 5; do
echo -n "间隔 ${interval}s: "
result=$(ping -c 5 -i $interval -W 1 "$target" 2>/dev/null | grep "rtt" | awk -F'/' '{print $2}')
if [ -n "$result" ]; then
echo "$result ms"
else
echo "测试失败"
fi
done
}
# 5. 网络中断检测
network_outage_detection() {
local target=${1:-"8.8.8.8"}
local duration=${2:-3600} # 默认监控1小时
local interval=${3:-5} # 默认5秒间隔
echo -e "${BLUE}=== 网络中断检测 ===${NC}"
echo "监控目标: $target"
echo "监控时长: ${duration}秒"
echo "检查间隔: ${interval}秒"
echo ""
local start_time=$(date +%s)
local end_time=$((start_time + duration))
local outages=0
local last_status="up"
while [ $(date +%s) -lt $end_time ]; do
if ping -c 1 -W 1 "$target" &> /dev/null; then
current_status="up"
else
current_status="down"
fi
# 检测状态变化
if [ "$current_status" != "$last_status" ]; then
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
if [ "$current_status" = "down" ]; then
echo -e "${RED}[$timestamp] 网络中断开始${NC}"
outages=$((outages + 1))
else
echo -e "${GREEN}[$timestamp] 网络恢复${NC}"
fi
last_status="$current_status"
fi
sleep "$interval"
done
echo -e "\n${YELLOW}监控结果:${NC}"
echo "总中断次数: $outages"
echo "监控时长: ${duration}秒"
}
# 6. 多目标监控
multi_target_monitoring() {
local targets=("8.8.8.8" "1.1.1.1" "9.9.9.9" "google.com")
local interval=${1:-10}
echo -e "${BLUE}=== 多目标网络监控 ===${NC}"
echo "监控间隔: ${interval}秒"
echo "按 Ctrl+C 停止"
echo ""
while true; do
clear
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo -e "${YELLOW}网络状态监控 - $timestamp${NC}"
echo "========================================"
for target in "${targets[@]}"; do
echo -n "$target: "
# 执行ping测试
if ping_result=$(ping -c 2 -W 1 "$target" 2>/dev/null); then
# 提取延迟
rtt=$(echo "$ping_result" | grep "rtt" | awk -F'/' '{print $2}')
loss=$(echo "$ping_result" | grep "packet loss" | awk '{print $6}')
if [ -n "$rtt" ]; then
echo -e "${GREEN}延迟: ${rtt}ms 丢包: ${loss}${NC}"
else
echo -e "${GREEN}可达${NC}"
fi
else
echo -e "${RED}不可达${NC}"
fi
done
sleep "$interval"
done
}
# 7. 主菜单
main_menu() {
while true; do
clear
echo -e "${BLUE}=== 网络故障排查和诊断工具 ===${NC}"
echo ""
echo "1. 网络连通性诊断"
echo "2. 网络质量测试"
echo "3. 路径MTU发现"
echo "4. 网络延迟故障排查"
echo "5. 网络中断检测"
echo "6. 多目标监控"
echo "7. 批量网络测试"
echo "8. 生成诊断报告"
echo "0. 退出"
echo ""
read -p "请选择操作: " choice
case $choice in
1)
read -p "目标地址 (默认 8.8.8.8): " target
network_diagnosis "${target:-8.8.8.8}"
;;
2)
read -p "目标地址 (默认 8.8.8.8): " target
read -p "数据包数量 (默认 20): " count
network_quality_test "${target:-8.8.8.8}" "${count:-20}"
;;
3)
read -p "目标地址 (默认 8.8.8.8): " target
path_mtu_discovery "${target:-8.8.8.8}"
;;
4)
read -p "目标地址 (默认 8.8.8.8): " target
latency_troubleshooting "${target:-8.8.8.8}"
;;
5)
read -p "目标地址 (默认 8.8.8.8): " target
read -p "监控时长(秒,默认3600): " duration
read -p "检查间隔(秒,默认5): " interval
network_outage_detection "${target:-8.8.8.8}" "${duration:-3600}" "${interval:-5}"
;;
6)
read -p "监控间隔(秒,默认10): " interval
multi_target_monitoring "${interval:-10}"
;;
7)
echo "批量网络测试..."
targets_file="/tmp/ping-targets.txt"
cat > "$targets_file" << 'EOF'
# 网络测试目标列表
8.8.8.8 Google DNS
1.1.1.1 Cloudflare DNS
9.9.9.9 Quad9 DNS
google.com Google
github.com GitHub
EOF
while read -r line; do
[[ "$line" =~ ^# ]] && continue
[[ -z "$line" ]] && continue
target=$(echo "$line" | awk '{print $1}')
description=$(echo "$line" | awk '{for(i=2;i<=NF;i++) printf $i" "}')
echo -e "\n测试: $description ($target)"
ping -c 2 -W 1 "$target" 2>/dev/null && echo -e "${GREEN}✓ 可达${NC}" || echo -e "${RED}✗ 不可达${NC}"
done < "$targets_file"
;;
8)
report_file="/tmp/network-diagnosis-$(date +%Y%m%d-%H%M%S).txt"
echo "生成诊断报告: $report_file"
{
echo "=== 网络诊断报告 ==="
echo "生成时间: $(date)"
echo "主机名: $(hostname)"
echo ""
network_diagnosis "8.8.8.8"
echo ""
network_quality_test "8.8.8.8" 10
} > "$report_file" 2>&1
echo -e "${GREEN}报告已生成: $report_file${NC}"
;;
0)
echo -e "${GREEN}退出${NC}"
exit 0
;;
*)
echo -e "${RED}无效选择${NC}"
;;
esac
echo ""
read -p "按回车键继续..."
done
}
# 运行主菜单
main_menu
ping的高级应用和自动化脚本:
#!/bin/bash
# 高级ping应用和脚本
# 1. 网络监控系统
network_monitoring_system() {
local config_file="/etc/network-monitor.conf"
# 创建配置文件
cat > "$config_file" << 'EOF'
# 网络监控配置
MONITOR_INTERVAL=60
ALERT_EMAIL="admin@example.com"
LOG_FILE="/var/log/network-monitor.log"
# 监控目标
TARGETS=(
"8.8.8.8:Google DNS"
"1.1.1.1:Cloudflare DNS"
"192.168.1.1:Gateway"
"google.com:Google"
)
# 报警阈值
PACKET_LOSS_THRESHOLD=10 # 丢包率超过10%报警
LATENCY_THRESHOLD=200 # 延迟超过200ms报警
TIMEOUT_THRESHOLD=3 # 连续3次超时报警
EOF
# 监控脚本
cat > /usr/local/bin/network-monitor.sh << 'EOF'
#!/bin/bash
# 网络监控脚本
source /etc/network-monitor.conf
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
send_alert() {
local subject=$1
local message=$2
log_message "ALERT: $subject - $message"
# 发送邮件
echo "$message" | mail -s "网络监控报警: $subject" "$ALERT_EMAIL"
# 发送系统日志
logger -p user.alert "网络监控: $subject - $message"
}
monitor_target() {
local target=$1
local description=$2
# 执行ping测试
ping_result=$(ping -c 5 -W 1 "$target" 2>/dev/null)
if [ $? -eq 0 ]; then
# 解析结果
packet_loss=$(echo "$ping_result" | grep "packet loss" | awk '{print $6}' | cut -d'%' -f1)
avg_latency=$(echo "$ping_result" | grep "rtt" | awk -F'/' '{print $2}')
# 检查阈值
if [ -n "$packet_loss" ] && [ "$packet_loss" -gt "$PACKET_LOSS_THRESHOLD" ]; then
send_alert "高丢包率" "$description ($target) 丢包率: ${packet_loss}%"
fi
if [ -n "$avg_latency" ] && (( $(echo "$avg_latency > $LATENCY_THRESHOLD" | bc -l) )); then
send_alert "高延迟" "$description ($target) 平均延迟: ${avg_latency}ms"
fi
log_message "INFO: $description ($target) - 丢包: ${packet_loss}%, 延迟: ${avg_latency}ms"
else
# 记录超时
echo "1" >> "/tmp/${target//./_}-timeout"
timeout_count=$(cat "/tmp/${target//./_}-timeout" 2>/dev/null | wc -l)
if [ "$timeout_count" -ge "$TIMEOUT_THRESHOLD" ]; then
send_alert "连接超时" "$description ($target) 连续 $timeout_count 次超时"
fi
log_message "ERROR: $description ($target) - 连接超时"
fi
}
# 主监控循环
while true; do
for target_info in "${TARGETS[@]}"; do
target=$(echo "$target_info" | cut -d':' -f1)
description=$(echo "$target_info" | cut -d':' -f2)
monitor_target "$target" "$description"
done
sleep "$MONITOR_INTERVAL"
done
EOF
chmod +x /usr/local/bin/network-monitor.sh
# 创建systemd服务
cat > /etc/systemd/system/network-monitor.service << EOF
[Unit]
Description=Network Monitoring Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/network-monitor.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
echo "网络监控系统已配置"
echo "配置文件: $config_file"
echo "监控脚本: /usr/local/bin/network-monitor.sh"
echo "Systemd服务: /etc/systemd/system/network-monitor.service"
}
# 2. 网络性能基准测试
network_benchmark() {
local target=${1:-"8.8.8.8"}
local output_file="/tmp/network-benchmark-$(date +%Y%m%d-%H%M%S).csv"
echo "网络性能基准测试: $target"
echo "输出文件: $output_file"
echo ""
# CSV头部
echo "时间戳,数据包大小,间隔,丢包率,最小延迟,平均延迟,最大延迟,抖动" > "$output_file"
# 测试不同参数组合
sizes=(64 128 256 512 1024 1472)
intervals=(0.1 0.5 1 2)
for size in "${sizes[@]}"; do
for interval in "${intervals[@]}"; do
echo -n "测试: ${size}字节, ${interval}秒间隔..."
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# 执行测试
result=$(ping -c 20 -s $size -i $interval -W 1 "$target" 2>/dev/null)
if [ $? -eq 0 ]; then
packet_loss=$(echo "$result" | grep "packet loss" | awk '{print $6}' | cut -d'%' -f1)
rtt_stats=$(echo "$result" | grep "rtt" | awk -F'=' '{print $2}' | tr '/' ',')
if [ -n "$rtt_stats" ]; then
echo "$timestamp,$size,$interval,$packet_loss,$rtt_stats" >> "$output_file"
echo " 完成"
else
echo "$timestamp,$size,$interval,$packet_loss,,,,," >> "$output_file"
echo " 完成(无RTT数据)"
fi
else
echo "$timestamp,$size,$interval,100,,,,," >> "$output_file"
echo " 失败"
fi
done
done
echo ""
echo "基准测试完成"
echo "结果文件: $output_file"
# 生成简单报告
echo "=== 基准测试摘要 ==="
awk -F',' 'NR>1 {print $0}' "$output_file" | head -5
}
# 3. 网络拓扑发现
network_topology_discovery() {
local network=${1:-"192.168.1.0/24"}
echo "网络拓扑发现: $network"
echo ""
# 提取网络地址和掩码
net_addr=$(echo "$network" | cut -d'/' -f1)
net_mask=$(echo "$network" | cut -d'/' -f2)
# 计算主机范围
if [ "$net_mask" = "24" ]; then
for i in {1..254}; do
host="${net_addr%.*}.$i"
echo -n "扫描 $host: "
# 快速ping扫描
if ping -c 1 -W 1 "$host" &> /dev/null; then
# 获取主机名
hostname=$(nslookup "$host" 2>/dev/null | grep "name =" | awk '{print $4}')
# 获取MAC地址
mac=$(arp -n "$host" 2>/dev/null | awk '{print $3}')
# 获取开放端口
ports=$(nmap -p 22,80,443,3389 --open "$host" 2>/dev/null | grep open | awk -F'/' '{print $1}' | tr '\n' ',')
echo -e "\e[32m活跃\e[0m - 主机名: ${hostname:-N/A}, MAC: ${mac:-N/A}, 端口: [${ports%,}]"
else
echo -e "\e[31m不活跃\e[0m"
fi
done
else
echo "只支持/24网络扫描"
fi
}
# 4. DDOS攻击检测
ddos_detection() {
local interface=${1:-"eth0"}
local threshold=${2:-100} # 每秒100个ICMP包
echo "DDOS攻击检测"
echo "监控接口: $interface"
echo "阈值: ${threshold}个ICMP包/秒"
echo "按 Ctrl+C 停止"
echo ""
# 使用tcpdump监控ICMP流量
sudo tcpdump -i "$interface" -n icmp 2>/dev/null | while read line; do
# 提取源IP
src_ip=$(echo "$line" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -1)
if [ -n "$src_ip" ]; then
# 记录时间戳
timestamp=$(date +%s)
# 记录到临时文件
echo "$timestamp:$src_ip" >> /tmp/icmp-traffic.log
# 清理旧记录(5秒前)
five_sec_ago=$((timestamp - 5))
grep -v ":$five_sec_ago:" /tmp/icmp-traffic.log > /tmp/icmp-traffic.tmp
mv /tmp/icmp-traffic.tmp /tmp/icmp-traffic.log
# 统计最近5秒的ICMP包
recent_count=$(grep ":$src_ip$" /tmp/icmp-traffic.log | wc -l)
if [ "$recent_count" -gt "$threshold" ]; then
echo "警告: 检测到可能的ICMP洪水攻击来自 $src_ip ($recent_count 个包/5秒)"
logger -p user.alert "DDOS检测: ICMP洪水攻击来自 $src_ip"
fi
fi
done
}
# 5. 智能网络诊断
intelligent_network_diagnosis() {
local target=${1:-"8.8.8.8"}
echo "智能网络诊断: $target"
echo ""
# 收集诊断信息
local_info() {
echo "=== 本地网络信息 ==="
echo "主机名: $(hostname)"
echo "IP地址: $(hostname -I)"
echo "网关: $(ip route | grep default | awk '{print $3}')"
echo "DNS服务器: $(grep nameserver /etc/resolv.conf | head -2)"
echo ""
}
# 路径追踪
path_trace() {
echo "=== 路径追踪 ==="
traceroute -n -q 1 -w 1 "$target" 2>/dev/null | head -10
echo ""
}
# 多角度ping测试
multi_ping_test() {
echo "=== 多角度Ping测试 ==="
# 测试不同大小的数据包
echo "1. 不同数据包大小测试:"
for size in 64 128 256 512 1024 1472; do
result=$(ping -c 2 -s $size -W 1 "$target" 2>/dev/null | grep "rtt" | awk -F'/' '{print $2 "ms"}')
echo " $size 字节: ${result:-超时}"
done
echo ""
# 测试不同TTL
echo "2. 不同TTL测试:"
for ttl in 1 8 16 32 64; do
if ping -c 1 -t $ttl -W 1 "$target" 2>/dev/null | grep -q "Time to live exceeded"; then
echo " TTL $ttl: 在 $ttl 跳内可达"
else
echo " TTL $ttl: 需要超过 $ttl 跳"
fi
done
echo ""
}
# MTU测试
mtu_test() {
echo "=== MTU测试 ==="
# 常见MTU值测试
for mtu in 576 1280 1492 1500 9000; do
size=$((mtu - 28))
if ping -c 1 -s $size -M do "$target" &> /dev/null; then
echo " MTU $mtu: 支持"
else
echo " MTU $mtu: 不支持 (可能需要分片)"
fi
done
echo ""
}
# 网络质量评估
quality_assessment() {
echo "=== 网络质量评估 ==="
# 执行详细ping测试
result=$(ping -c 20 -i 0.2 -W 1 "$target" 2>/dev/null)
if [ $? -eq 0 ]; then
packet_loss=$(echo "$result" | grep "packet loss" | awk '{print $6}')
rtt_stats=$(echo "$result" | grep "rtt" | awk -F'=' '{print $2}')
echo "丢包率: $packet_loss"
echo "延迟统计: $rtt_stats"
# 质量评级
loss_percent=$(echo "$packet_loss" | cut -d'%' -f1)
avg_rtt=$(echo "$rtt_stats" | awk -F'/' '{print $2}')
score=100
# 根据丢包率扣分
if [ "$loss_percent" -gt 20 ]; then
score=$((score - 50))
elif [ "$loss_percent" -gt 10 ]; then
score=$((score - 30))
elif [ "$loss_percent" -gt 5 ]; then
score=$((score - 20))
elif [ "$loss_percent" -gt 1 ]; then
score=$((score - 10))
fi
# 根据延迟扣分
if (( $(echo "$avg_rtt > 300" | bc -l 2>/dev/null) )); then
score=$((score - 30))
elif (( $(echo "$avg_rtt > 200" | bc -l 2>/dev/null) )); then
score=$((score - 20))
elif (( $(echo "$avg_rtt > 100" | bc -l 2>/dev/null) )); then
score=$((score - 10))
fi
# 显示评级
echo "质量评分: $score/100"
if [ "$score" -ge 90 ]; then
echo "评级: 优秀 ✓"
elif [ "$score" -ge 70 ]; then
echo "评级: 良好 ✓"
elif [ "$score" -ge 50 ]; then
echo "评级: 一般 ⚠"
else
echo "评级: 差 ✗"
fi
else
echo "无法评估: 目标不可达"
fi
echo ""
}
# 问题诊断
problem_diagnosis() {
echo "=== 问题诊断 ==="
# 检查常见问题
echo "检查以下常见问题:"
echo ""
# 检查DNS
if ! nslookup google.com &> /dev/null; then
echo "1. DNS解析问题: 无法解析域名 ✗"
else
echo "1. DNS解析: 正常 ✓"
fi
# 检查网关
gateway=$(ip route | grep default | awk '{print $3}')
if [ -n "$gateway" ] && ping -c 1 -W 1 "$gateway" &> /dev/null; then
echo "2. 网关连通性: 正常 ✓"
else
echo "2. 网关连通性: 有问题 ✗"
fi
# 检查外部网络
if ping -c 1 -W 1 8.8.8.8 &> /dev/null; then
echo "3. 外部网络: 正常 ✓"
else
echo "3. 外部网络: 有问题 ✗"
fi
# 检查目标可达性
if ping -c 1 -W 1 "$target" &> /dev/null; then
echo "4. 目标可达性: 正常 ✓"
else
echo "4. 目标可达性: 有问题 ✗"
fi
echo ""
}
# 执行所有诊断
local_info
path_trace
multi_ping_test
mtu_test
quality_assessment
problem_diagnosis
# 生成建议
echo "=== 建议 ==="
echo "1. 如果DNS有问题: 检查/etc/resolv.conf配置"
echo "2. 如果网关有问题: 检查网络连接和网关配置"
echo "3. 如果延迟过高: 联系ISP或优化网络路由"
echo "4. 如果丢包严重: 检查网络设备或联系ISP"
echo "5. 定期运行网络监控: 使用network-monitor.sh"
}
# 6. 主菜单
main_menu() {
while true; do
clear
echo "=== 高级ping应用和脚本 ==="
echo ""
echo "1. 配置网络监控系统"
echo "2. 网络性能基准测试"
echo "3. 网络拓扑发现"
echo "4. DDOS攻击检测"
echo "5. 智能网络诊断"
echo "6. 批量网络质量测试"
echo "7. 创建自定义ping工具"
echo "8. 网络历史数据分析"
echo "0. 退出"
echo ""
read -p "请选择操作: " choice
case $choice in
1) network_monitoring_system ;;
2)
read -p "目标地址 (默认 8.8.8.8): " target
network_benchmark "${target:-8.8.8.8}"
;;
3)
read -p "网络地址 (如 192.168.1.0/24): " network
network_topology_discovery "${network:-192.168.1.0/24}"
;;
4)
read -p "监控接口 (默认 eth0): " interface
read -p "报警阈值 (默认 100): " threshold
ddos_detection "${interface:-eth0}" "${threshold:-100}"
;;
5)
read -p "目标地址 (默认 8.8.8.8): " target
intelligent_network_diagnosis "${target:-8.8.8.8}"
;;
6)
echo "批量网络质量测试..."
targets=("8.8.8.8" "1.1.1.1" "9.9.9.9" "google.com" "github.com")
for target in "${targets[@]}"; do
echo "测试: $target"
ping -c 10 -i 0.2 "$target" 2>/dev/null | tail -2
echo ""
done
;;
7)
echo "创建自定义ping工具..."
cat > /tmp/custom-ping.sh << 'EOF'
#!/bin/bash
# 自定义ping工具
VERSION="1.0"
AUTHOR="网络诊断工具包"
show_help() {
cat << HELP
自定义ping工具 v$VERSION
用法: $0 [选项] 目标地址
选项:
-c, --count NUM 发送指定数量的数据包
-s, --size NUM 设置数据包大小(字节)
-i, --interval NUM 设置发送间隔(秒)
-t, --timeout NUM 设置超时时间(秒)
-q, --quiet 安静模式,只显示统计
-v, --verbose 详细模式,显示更多信息
-h, --help 显示此帮助信息
-V, --version 显示版本信息
示例:
$0 -c 10 -i 0.5 google.com
$0 --size 1000 --timeout 2 8.8.8.8
HELP
}
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-c|--count)
COUNT="$2"
shift 2
;;
-s|--size)
SIZE="$2"
shift 2
;;
-i|--interval)
INTERVAL="$2"
shift 2
;;
-t|--timeout)
TIMEOUT="$2"
shift 2
;;
-q|--quiet)
QUIET=1
shift
;;
-v|--verbose)
VERBOSE=1
shift
;;
-h|--help)
show_help
exit 0
;;
-V|--version)
echo "自定义ping工具 v$VERSION"
echo "作者: $AUTHOR"
exit 0
;;
-*)
echo "未知选项: $1"
show_help
exit 1
;;
*)
TARGET="$1"
shift
;;
esac
done
# 检查目标地址
if [ -z "$TARGET" ]; then
echo "错误: 需要指定目标地址"
show_help
exit 1
fi
# 构建ping命令
PING_CMD="ping"
[ -n "$COUNT" ] && PING_CMD="$PING_CMD -c $COUNT"
[ -n "$SIZE" ] && PING_CMD="$PING_CMD -s $SIZE"
[ -n "$INTERVAL" ] && PING_CMD="$PING_CMD -i $INTERVAL"
[ -n "$TIMEOUT" ] && PING_CMD="$PING_CMD -W $TIMEOUT"
[ -n "$QUIET" ] && PING_CMD="$PING_CMD -q"
[ -n "$VERBOSE" ] && PING_CMD="$PING_CMD -v"
# 执行ping
echo "执行: $PING_CMD $TARGET"
echo ""
$PING_CMD "$TARGET"
EOF
chmod +x /tmp/custom-ping.sh
echo "自定义ping工具已创建: /tmp/custom-ping.sh"
;;
8)
echo "网络历史数据分析..."
# 分析ping日志
if [ -f "/var/log/ping-monitor.log" ]; then
echo "分析ping监控日志..."
echo "总记录数: $(wc -l < /var/log/ping-monitor.log)"
echo "网络中断次数: $(grep -c "网络中断" /var/log/ping-monitor.log)"
echo "最近5次中断:"
grep "网络中断" /var/log/ping-monitor.log | tail -5
else
echo "没有找到ping监控日志"
fi
;;
0)
echo "退出"
exit 0
;;
*)
echo "无效选择"
;;
esac
echo ""
read -p "按回车键继续..."
done
}
# 运行主菜单
main_menu
ping 命令如果被滥用,可能对网络造成严重影响:
ping -f 可能造成网络拥塞安全建议:
ping -f| icmp_seq | ICMP序列号,表示第几个数据包 |
| ttl | 生存时间,每经过一个路由器减1,用于防止数据包无限循环 |
| time | 往返时间(RTT),单位毫秒(ms) |
| packets transmitted | 发送的数据包总数 |
| packets received | 接收到的数据包总数 |
| packet loss | 丢包率,网络质量的重要指标 |
| rtt min/avg/max/mdev | 最小/平均/最大往返时间和平均偏差 |
可能原因: DNS解析失败
解决方案:
# 检查DNS配置
cat /etc/resolv.conf
# 测试DNS解析
nslookup google.com
dig google.com
# 直接使用IP地址测试
ping -n 8.8.8.8
可能原因: 本地路由问题或目标主机不存在
解决方案:
# 检查本地路由表
route -n
# 检查网络接口配置
ifconfig -a
ip addr show
# 尝试ping网关
ping 192.168.1.1 # 替换为你的网关地址
可能原因: 目标主机禁用了ICMP或防火墙阻挡
解决方案:
# 使用traceroute检查路由路径
traceroute google.com
# 尝试不同的目标主机
ping baidu.com
# 检查防火墙设置
sudo iptables -L -n
ping6 命令(在某些系统中,ping 也支持 IPv6)traceroute跟踪数据包经过的路由路径
mtr结合 ping 和 traceroute 功能的网络诊断工具
netstat显示网络连接、路由表、接口统计等信息
nslookupDNS 查询工具
ifconfig网络接口配置工具
ip现代网络配置工具(替代 ifconfig)