Files
cs-note/hhs/NETWORK/07-网络工具与诊断/01-连通性与状态探测工具.md
T
2026-05-24 11:42:38 +08:00

7.4 KiB
Raw Blame History

tags, create time
tags create time
计算机网络
ping
traceroute
ss
telnet
nc
netstat
2026-05-18 04:45

连通性与状态探测工具

概述

排查网络问题时,正确的第一步是判断"到底通不通"。本章覆盖从物理连通性到应用端口层的基础探测工具。

ping —— ICMP Echo Request/Reply

基本用法速查

$ 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 综合判断。

# 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 —— 最原始的端口探测

# 纯测试端口是否开放
$ 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) —— 更强大的瑞士军刀

# 仅测试端口连通 (-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 基础用法

# 查看所有 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 ⚠️ 罕见
# 按状态过滤
$ 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 —— 逐跳路径探测

三种实现方式

# 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 原理

flowchart LR
    P1["TTL=1 → 第1跳路由器<br/>回 ICMP Time Exceeded"] -->|"RTT₁"| R1["第1跳: 192.168.1.1"]
    P2["TTL=2 → 第2跳路由器<br/>回 ICMP Time Exceeded"] -->|"RTT₂"| R2["第2跳: 10.0.0.1"]
    P3["TTL=N → 到达目标<br/>回 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
# 识别路由问题
$ 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 问题

关联笔记