--- tags: [计算机网络, ping, traceroute, ss, telnet, nc, netstat] create time: 2026-05-18 04:45 --- # 连通性与状态探测工具 ## 概述 排查网络问题时,正确的第一步是判断"到底通不通"。本章覆盖从物理连通性到应用端口层的基础探测工具。 ## ping —— ICMP Echo Request/Reply ### 基本用法速查 ```bash $ ping -c 4 example.com # 发 4 个包后自动停止 $ ping -i 0.2 example.com # 每 0.2s 发一个(需 root) $ ping -s 1472 example.com # 载荷 1472 bytes (接近 MTU 1500) $ ping -t 64 example.com # 指定初始 TTL $ ping -q example.com # 静默模式,仅显示统计摘要 $ ping -W 2 example.com # 每个包的超时等待 2 秒 ``` ### 解读输出指标 ``` PING example.com (93.184.216.34) 56(84) bytes of data. 64 bytes from 93.184.216.34: icmp_seq=1 ttl=56 time=14.2 ms 64 bytes from 93.184.216.34: icmp_seq=2 ttl=56 time=13.8 ms --- example.com ping statistics --- packets transmitted: 2 # 发送包数 packet loss: 0% # 丢包率 rtt min/avg/max/mdev = 13.8/14.0/14.2/0.2 ms # 往返时间统计 ``` | 指标 | 含义 | 合格阈值 | |------|------|---------| | packet loss | 丢包率 | 0% ~ 0.1%(局域网不应有丢包)| | rtt avg | 平均 RTT | LAN < 1ms / 同城 < 20ms / 跨省 30-80ms / 跨洋 80-150ms | | mdev | RTT 标准差 | < 5ms 正常;抖动大说明拥塞或不稳定 | > [!warning] ping 不通 ≠ 网络故障 > > 很多服务器禁用了 ICMP Echo Reply(防火墙策略),此时 ping 不通不代表服务不可用。需要结合 `telnet port` 或 `curl` 综合判断。 ```bash # Linux 内置的 ICMP 防御(防 DDoS flood) $ sysctl net.ipv4.icmp_ratelimit=1000 # 每秒最多处理 1000 个 ICMP 包 $ sysctl net.ipv4.icmp_ratemask=65535 # 允许的 ICMP 类型掩码 $ sysctl net.ipv4.icmp_echo_ignore_all=1 # 完全忽略所有 ping(极端场景) ``` ## telnet / nc —— 端口连通测试 ### telnet —— 最原始的端口探测 ```bash # 纯测试端口是否开放 $ telnet example.com 80 Trying 93.184.216.34... Connected to example.com. # ← Connected = 端口开放 ✅ Escape character is '^]'. # 手动发 HTTP 请求测试 GET / HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 Accept: */* (blank line 回车) HTTP/1.1 200 OK # ← 收到响应 = 链路完整 ✅ Content-Type: text/html ... ``` ### nc (Netcat) —— 更强大的瑞士军刀 ```bash # 仅测试端口连通 (-z = zero-I/O 模式) $ nc -zv example.com 80 Connection to example.com port 80 [http] succeeded! # ✅ TCP 3次握手成功 $ nc -zv example.com 443 Connection to example.com port 443 [https] succeeded! # ✅ $ nc -zv example.com 8443 nc: connect to example.com port 8443 (tcp): Connection refused # ❌ # 发送数据并等待响应 $ echo "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | nc -w 2 example.com 80 | head -5 # DNS 反向查询 $ nc -dvl 0.0.0.0 12345 # 监听模式 $ nc -u -z localhost 53 # UDP 端口测试 (DNS 常用) ``` ## ss —— 连接状态快照(取代 netstat) ### ss 基础用法 ```bash # 查看所有 TCP 连接(数字格式,不解析域名) $ ss -tan State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 192.168.1.10:45678 93.184.216.34:443 users:(("chrome",pid=1234,fd=42)) SYN-SENT 0 1 192.168.1.10:54321 10.0.0.1:8080 # 正在尝试握手 LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=5678,fd=6)) TIME-WAIT 0 0 192.168.1.10:443 93.184.216.34:52341 # 等待 2MSL # 查看特定端口的监听 $ ss -tlnp sport = :80 LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=5678,fd=6)) # 查看所有 TIME_WAIT 连接数(高并发服务器常见问题) $ ss -tan state time-wait | wc -l 1247 # 查看某进程的所有连接 $ ss -tnp | grep nginx | wc -l # 诊断 CLOSE_WAIT 堆积(⚠️ 代码 Bug!) $ ss -tan state close-wait CLOSE-WAIT 0 0 server:8080 client:54321 # ← 对端已关闭,本地未 close()! ``` ### ss 状态速查表 | ss 状态 | 含义 | 严重程度 | |---------|------|---------| | ESTABLISHED | 正常通信中 | ✅ 正常 | | LISTEN | 等待接受连接 | ✅ 正常 | | SYN-SENT | 客户端发出的 SYN 未收到回复 | ⚠️ 检查对端是否存活 | | SYN-RECV | 收到 SYN 但未完成三次握手 | ⚠️ 可能 SYN Flood | | TIME-WAIT | 己方主动关闭后等待 2MSL | ⚠️ 可调 tcp_tw_reuse | | CLOSE-WAIT | 对端关闭但己方未 close() | 🔴 **Bug!** 检查代码 | | LAST-ACK | 等待最后一个 ACK | ⚠️ 短暂状态,持续则异常 | | CLOSING | 同时关闭,互等对方 ACK | ⚠️ 罕见 | ```bash # 按状态过滤 $ ss -tan state established # 仅已建立 $ ss -tan state syn-sent # 仅半连接中 $ ss -tan state closing # 仅 CLOSING # 按源/目标 IP 过滤 $ ss -tn daddr 10.0.0.0/8 # 只看内网连接 $ ss -tn src :80 # 只看来自 80 端的 ``` > [!tip] ss vs netstat > `ss` 使用 netlink socket 替代 `/proc/net/tcp`,速度更快、信息更全。Linux 5.x+ 系统上 netstat 已被标记为 deprecated。 ## traceroute —— 逐跳路径探测 ### 三种实现方式 ```bash # UDP 模式(默认)—— 向高端口发 UDP 包递增 TTL $ traceroute -n example.com 1 192.168.1.1 0.5ms 0.3ms 0.4ms 2 10.0.0.1 10.2ms 9.8ms 10.1ms 12 93.184.216.34 45.1ms 44.8ms 45.0ms # ICMP 模式(更可靠,不容易被防火墙拦截) $ traceroute -I example.com # 现代替代:tracepath(不需要 root,自动 PMTUD) $ tracepath example.com 1: 192.168.1.1 0ms reached 2: 10.0.0.1 10ms ... 12: 93.184.216.34 45ms Ascent peak pmtu 1452 ``` ### traceroute 原理 ```mermaid flowchart LR P1["TTL=1 → 第1跳路由器
回 ICMP Time Exceeded"] -->|"RTT₁"| R1["第1跳: 192.168.1.1"] P2["TTL=2 → 第2跳路由器
回 ICMP Time Exceeded"] -->|"RTT₂"| R2["第2跳: 10.0.0.1"] P3["TTL=N → 到达目标
回 ICMP Port Unreachable"] -->|"RTTN"| Rn["目的地: 93.184.216.34"] style R1 fill:#DDA0DD,color:#000 style R2 fill:#FFD700,color:#000 style Rn fill:#98FB98,color:#000 ``` ```bash # 识别路由问题 $ traceroute -n 8.8.8.8 ... 5 * * * # ← 这里丢了?→ 路由器禁了 ICMP 6 * * * # ← 可能是运营商之间互联点 7 108.170.xxx.xxx 50ms 48ms 51ms # ← 回到 Google 边缘 # Windows 等价命令 tracert 8.8.8.8 # macOS 等价命令 traceroute 8.8.8.8 ``` ## 排错黄金思路回顾 ``` 问题: 无法访问服务 ↓ ping 通吗? → 否 → traceroute 定位断在哪一跳 ↓ 是 telnet port 通吗? → 否 → 检查防火墙/selinux → ss 看是否监听 ↓ 是 curl 正常吗? → 否 → 应用层问题 → 读日志 ↓ 是 浏览器缓存/Cookie/Header 问题 ``` ## 关联笔记 - [[hhs/NETWORK/ICMP与Ping-Traceroute]] — ping/traceroute 的协议底层原理 - [[hhs/NETWORK/TCP三次握手与四次挥手]] — ss 中看到的状态都对应 TCP 状态机中的某个节点 - [[hhs/NETWORK/DNS与DHCP与WebSocket]] — DNS 解析慢会影响 ping/curl 的表现 - [[hhs/NETWORK/抓包HTTPDNS诊断工具]] — 进一步分析可用 tcpdump/curl/dig