netstat 与 ss 深度详解

16 阅读5分钟

一、netstat(传统工具)

1. 基本介绍

  • 全称:Network Statistics
  • 出现时间:1980年代,UNIX 系统
  • 特点
    • 功能全面,历史悠久
    • 通过读取 /proc/net/ 目录获取信息
    • 在某些场景下较慢(特别是连接数多时)

2. 常用命令详解

查看所有连接

netstat -a                    # 所有连接(TCP/UDP/UNIX Socket)
netstat -at                   # 所有TCP连接
netstat -au                   # 所有UDP连接

查看监听端口

netstat -l                    # 所有监听
netstat -lt                   # 监听TCP端口
netstat -lu                   # 监听UDP端口
netstat -lx                   # 监听UNIX域套接字

显示进程信息

netstat -p                    # 显示PID/程序名
netstat -tp                   # TCP + 进程信息
netstat -lp                   # 监听端口 + 进程信息

显示数字格式

netstat -n                    # 不解析主机名
netstat -nt                   # TCP + 数字格式
netstat -nu                   # UDP + 数字格式

组合使用

netstat -tunlp                # 常用组合:TCP/UDP + 数字 + 监听 + 进程
netstat -anp | grep :80       # 查找80端口

3. 统计信息

netstat -s                    # 所有协议统计
netstat -st                   # TCP统计
netstat -su                   # UDP统计

# 显示统计信息示例
$ netstat -st
Tcp:
    12345 active connections openings
    23456 passive connections openings
    345 failed connection attempts
    ...

4. 路由表信息

netstat -r                    # 显示路由表
netstat -rn                   # 数字格式路由表
netstat -r -e                 # 扩展信息

5. 接口信息

netstat -i                    # 网络接口统计
netstat -ie                   # 扩展接口信息
netstat -ic                   # 持续监控

6. 分组显示

netstat --tcp --listen --programs --numeric
# 等价于 netstat -tlnp

二、ss(现代替代品)

1. 基本介绍

  • 全称:Socket Statistics
  • 出现时间:2000年代,iproute2 套件
  • 特点
    • 速度快:直接从内核空间获取信息
    • 信息更详细:显示更多TCP内部状态
    • 过滤能力强:强大的过滤语法

2. 速度对比

# 测试命令耗时
time netstat -ant > /dev/null
time ss -ant > /dev/null

# 结果对比(10万连接时):
# netstat: 2-3秒
# ss: 0.1-0.2秒

3. 常用命令详解

查看所有TCP连接

ss -t      # TCP连接
ss -u      # UDP连接
ss -x      # UNIX域套接字
ss -w      # RAW套接字
ss -l      # 监听端口

显示数字格式

ss -n      # 不解析服务名
ss -tn     # TCP + 数字格式
ss -uln    # UDP监听 + 数字

显示进程信息

ss -p      # 显示进程
ss -tp     # TCP + 进程
ss -lp     # 监听 + 进程
ss -ntp    # 常用组合

显示详细扩展信息

ss -e      # 扩展信息(UID,inode等)
ss -tem    # TCP + 扩展 + 内存信息
ss -o      # 计时器信息
ss -tmio   # 综合信息

4. 强大的过滤功能

状态过滤

# TCP状态过滤
ss -t state established
ss -t state listening
ss -t state time-wait
ss -t state fin-wait-1

# 多个状态组合
ss -t state time-wait '( sport = :443 or sport = :80 )'

# 所有状态列表
ss -t state all
ss -t state connected      # 所有已连接状态
ss -t state synchronized   # 所有同步状态

地址/端口过滤

# 源地址过滤
ss dst 192.168.1.1
ss src 192.168.1.0/24

# 端口过滤
ss dport = :80
ss sport = :22
ss dport \> :1024

# 组合过滤
ss -t '( dport = :80 or dport = :443 )'
ss -t 'src 192.168.1.100 and dst 10.0.0.1'

高级过滤

# 过滤特定进程
ss -tp | grep nginx

# 过滤连接时间
ss -nto state established | grep 'timer:'

# 过滤接收/发送队列
ss -nt '( dport = :80 and recv-q > 0 )'

5. 统计信息

ss -s      # 简洁统计(推荐)
ss -ts     # TCP统计
ss -us     # UDP统计

# 输出示例
$ ss -s
Total: 1234 (kernel 2345)
TCP:   5678 (estab 123, closed 5432, orphaned 0, synrecv 0, timewait 5432/0), ports 0

Transport Total     IP        IPv6
*         2345      -         -
RAW       1         1         0
UDP       23        12        11
TCP       456       345       111
INET      480       358       122
FRAG      0         0         0

三、功能对比表

功能netstatss说明
基本连接查看两者都支持
进程信息-p 参数
数字格式-n 参数
监听端口-l 参数
统计信息-s 参数
路由表ss 不支持路由
接口统计ss 不支持接口
速度连接多时差异明显
过滤功能ss 有强大过滤语法
TCP状态过滤复杂简单ss state established
扩展信息有限丰富内存、计时器等
UNIX Socket两者都支持

四、实际使用示例

场景1:查找占用80端口的进程

# netstat 方式
netstat -tlnp | grep :80
netstat -anp | grep :80 | grep LISTEN

# ss 方式(更快更精确)
ss -ltnp 'sport = :80'
ss -tlnp | grep :80

场景2:查看已建立的HTTP连接

# netstat(较麻烦)
netstat -ant | grep ESTABLISHED | grep :80

# ss(简洁)
ss -t state established '( dport = :80 or dport = :443 )'

场景3:诊断TIME_WAIT问题

# netstat
netstat -ant | grep TIME_WAIT | wc -l
netstat -ant | awk '/^tcp/ {print $6}' | sort | uniq -c

# ss(更详细)
ss -t state time-wait
ss -t state time-wait | wc -l
ss -tan state time-wait | awk '{print $4}' | cut -d: -f2 | sort -n | uniq -c

场景4:监控连接状态变化

# 使用 watch 持续监控
watch -n 1 'ss -s'
watch -n 1 'ss -tan state established | wc -l'
watch -n 1 "ss -tn state time-wait | awk '{print \$5}' | cut -d: -f1 | sort | uniq -c"

五、高级用法

1. ss 的表达式语法

# 基本结构
ss [选项] [过滤表达式]

# 表达式组成
# 1. 过滤词:dst, src, dport, sport, state
# 2. 运算符:=, !=, <, >, <=, >=, eq, ne, gt, lt
# 3. 逻辑运算符:and, or, not

# 示例
ss -t '( dport = :80 or dport = :443 )'
ss -t 'src 192.168.1.0/24 and not dst 192.168.1.1'
ss -u 'sport = :53 and dst 8.8.8.8'

2. 显示TCP内部信息

# 查看TCP选项
ss -nti            # 显示TCP内部状态
ss -eti            # 扩展+TCP信息

# 查看缓冲区信息
ss -ntm            # 显示内存使用
ss -nt -o          # 显示计时器

# 解析输出示例
$ ss -nti
State   Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB   0      0      192.168.1.100:22   192.168.1.1:54321
     ts sack cubic wscale:7,7 rto:204 rtt:0.3/0.1 ato:40 mss:1448 cwnd:10 ssthresh:7 bytes_acked:12345 bytes_received:67890 segs_out:456 segs_in:789 send 1.5Mbps lastsnd:10 lastrcv:10 lastack:10 pacing_rate 3.0Mbps retrans:0/12 rcv_rtt:1 rcv_space:29200

3. 监控脚本示例

#!/bin/bash
# 网络连接监控脚本

INTERVAL=2
HOST=${1:-"0.0.0.0"}
PORT=${2:-"80"}

echo "监控连接: $HOST:$PORT"
echo "时间戳      ESTAB TIME_WAIT CLOSE_WAIT 总连接数"
echo "------------------------------------------------"

while true; do
    estab=$(ss -tan "dst $HOST:$PORT" state established | wc -l)
    timewait=$(ss -tan "dst $HOST:$PORT" state time-wait | wc -l)
    closewait=$(ss -tan "dst $HOST:$PORT" state close-wait | wc -l)
    total=$((estab + timewait + closewait))
    
    printf "%s %6d %10d %11d %10d\n" \
        "$(date '+%H:%M:%S')" \
        $estab $timewait $closewait $total
    
    # 异常检测
    if [ $closewait -gt 100 ]; then
        echo "警告: CLOSE_WAIT 过多!"
        ss -tanp "dst $HOST:$PORT" state close-wait | head -5
    fi
    
    sleep $INTERVAL
done

六、迁移指南:从 netstat 到 ss

常用命令对照表

netstat 命令ss 等效命令说明
netstat -tulpnss -tulpn查看监听端口
netstat -anpss -anp所有连接
netstat -rnip route show路由表
netstat -iip -s link接口统计
netstat -gip maddr show多播组
netstat -sss -s + nstat统计信息

转换脚本示例

#!/bin/bash
# netstat_to_ss.sh - 帮助转换命令

convert_command() {
    local netstat_cmd=$1
    
    case $netstat_cmd in
        "netstat -tulpn")
            echo "ss -tulpn"
            ;;
        "netstat -anp | grep :80")
            echo "ss -anp 'sport = :80 or dport = :80'"
            ;;
        "netstat -ant | grep ESTABLISHED | wc -l")
            echo "ss -tan state established | wc -l"
            ;;
        "netstat -rn")
            echo "ip route show"
            ;;
        "netstat -i")
            echo "ip -s link"
            ;;
        "netstat -s")
            echo "ss -s   # 摘要统计"
            echo "nstat   # 详细统计"
            ;;
        *)
            echo "无法转换的命令: $netstat_cmd"
            echo "尝试: ss -h 查看帮助"
            ;;
    esac
}

# 示例使用
convert_command "netstat -tulpn"

七、性能测试对比

测试脚本

#!/bin/bash
# 性能对比测试

echo "=== netstat vs ss 性能测试 ==="
echo "当前连接数: $(ss -tan state established | wc -l)"
echo ""

# 测试1: 所有TCP连接
echo "测试1: 显示所有TCP连接"
time (netstat -ant > /dev/null)
time (ss -ant > /dev/null)
echo ""

# 测试2: 已建立连接
echo "测试2: 显示已建立连接"
time (netstat -ant | grep ESTABLISHED > /dev/null)
time (ss -tan state established > /dev/null)
echo ""

# 测试3: 监听端口
echo "测试3: 显示监听端口"
time (netstat -tln > /dev/null)
time (ss -tln > /dev/null)

测试结果分析

环境:10万并发连接
netstat -ant:  2.34
ss -ant:       0.12   (快19倍)

netstat -tln:  0.45
ss -tln:       0.03   (快15倍)

八、最佳实践建议

1. 日常使用推荐

# 查看监听端口
alias ports='ss -tulpn'

# 查看已建立连接
alias conns='ss -tan state established'

# 查看连接统计
alias netstat='ss -s'

# 查看进程连接
alias netp='ss -tnp'

2. 故障排查组合命令

# 综合诊断
diagnose_network() {
    echo "=== 网络诊断 ==="
    echo "1. 监听端口:"
    ss -tulpn
    echo ""
    echo "2. 连接统计:"
    ss -s
    echo ""
    echo "3. 路由表:"
    ip route show
    echo ""
    echo "4. 接口状态:"
    ip -s link
}

3. .bashrc 配置

# 添加到 ~/.bashrc
alias netstat='echo "请使用 ss 命令替代 netstat,或使用 ip 命令"'
alias nstat='ss -s'
alias nlisten='ss -tulpn'
alias nconn='ss -tan state established'
alias ntimewait='ss -tan state time-wait'
alias nclosewait='ss -tan state close-wait'

九、常见问题解答

Q1: 为什么ss比netstat快?

netstat: 通过读取 /proc/net/tcp, /proc/net/udp 等文件
        → 用户空间解析 → 输出

ss: 使用 netlink 套接字直接从内核获取数据
        → 内核空间整理 → 直接输出
        (跳过文件系统开销)

Q2: 什么时候还用netstat?

  • 老系统没有 ss 命令
  • 需要查看路由表(netstat -rn
  • 需要接口统计(netstat -i
  • 脚本需要向后兼容

Q3: ss不支持的功能怎么办?

# 路由表
netstat -rn   →   ip route show

# 接口统计
netstat -i    →   ip -s link

# ARP缓存
netstat -an   →   ip neigh show

# 多播组
netstat -g    →   ip maddr show