# 网络测试

  • 常见的测试方式:
    • 用 ping 测试与某个主机的网络是否连通。这需要对方放通防火墙,并启用 ICMP 协议。
    • 用 telnet 测试能否访问到某个主机的某个端口。
    • 用 curl 测试能否访问到某个 HTTP 服务器。
    • 用 sar -n DEV 查看本机网络端口的收发速率。
    • 用 iperf 测试 TCP、UDP 的带宽。
    • 用 ab、wrk、Jmeter 进行 HTTP 压测。

# TCP/UDP 测试

# telnet

:一个陈旧的远程登录命令。

  • 通信内容没有加密,容易被监听。因此目前不适合用于远程登录,常用于测试 TCP 端口能否连通。
  • 命令:
    telnet <host> [port]    # 连接到某个主机(默认采用 TCP 23 端口)
    
  • 例:
    [root@CentOS ~]# telnet baidu.com 80
    Trying 39.156.69.79...
    Connected to baidu.com.
    Escape character is '^]'.
    
    
    • 可见它成功连接到目标主机的 80 端口。此时先后按 Ctrl + ]Ctrl + D 即可终止命令。

# nmap

:一个测试工具,用于端口扫描。

  • 安装:yum install nmap
  • 命令:
    nmap
        192.168.0.1               # 扫描目标主机有哪些端口可以连接
        192.168.0.1/24            # 扫描一个网段,检测有哪些可连接的主机,并扫描它们的端口
        192.168.0.1 192.168.0-5.1 # 扫描多个主机
        -p 80,443                 # 只扫描指定端口(默认扫描常用的 1000 个端口)
        -A                        # 扫描各种信息(比如推测目标主机的操作系统、版本)
        -v                        # 显示详细信息
    

# nc

  • netcat :一个命令行工具,于 1996 年发布,可进行简单的 TCP、UDP 通信,常用于测试端口能否连通。

    • nmap 项目开发了 ncat 命令,重新实现了 netcat 的功能。
    • 二者的命令缩写都为 nc 。
  • 安装:yum install nc

  • 命令:

    nc [options] [hostname] [port]
        -k        # --keep-open ,作为 TCP 服务器运行时,保持监听端口。默认接收一次连接就会终止命令
        -l        # 作为 TCP 或 UDP 服务器运行时,监听指定的端口
    
        -p <port> # 指定发送数据时,在 Socket 中 bind 的 port
        -s <IP>   # 指定发送数据时,在 Socket 中 bind 的 IP
    
        -u        # 采用 UDP 通信。默认为 TCP 通信
        -v        # --verbose
    
    • 用两个 nc 进程建立 TCP 或 UDP 连接之后,给任一个 nc 的 stdin 输入数据,都会传输到另一个 nc ,默认输出到 stdout 。
  • TCP 通信的示例:
    用 nc 监听 TCP 80 端口:

    [root@CentOS ~]# nc -klv 80
    Ncat: Version 7.50 ( https://nmap.org/ncat )
    Ncat: Listening on :::80
    Ncat: Listening on 0.0.0.0:80
    

    另开一个终端,用 nc 访问 TCP 80 端口:

    [root@CentOS ~]# nc -v 127.0.0.1 80
    Ncat: Version 7.50 ( https://nmap.org/ncat )
    Ncat: Connected to 127.0.0.1:80.
    

    同时,服务器端的 nc 的 stdout 如下:

    Ncat: Connection from 127.0.0.1.
    Ncat: Connection from 127.0.0.1:59700.
    

    执行 curl 127.0.0.1 ,服务器端的 nc 的 stdout 如下:

    Ncat: Connection from 127.0.0.1.
    Ncat: Connection from 127.0.0.1:57408.
    GET / HTTP/1.1
    User-Agent: curl/7.29.0
    Host: 127.0.0.1
    Accept: */*
    
  • UDP 通信的示例:
    用 nc 监听 UDP 80 端口:

    [root@CentOS ~]# nc -luv 80
    Ncat: Version 7.50 ( https://nmap.org/ncat )
    Ncat: Listening on :::80
    Ncat: Listening on 0.0.0.0:80
    

    另开一个终端,用 nc 访问 UDP 80 端口:

    [root@CentOS ~]# nc -uv 127.0.0.1 80
    Ncat: Version 7.50 ( https://nmap.org/ncat )
    Ncat: Connected to 127.0.0.1:80.
    
    • 此时显示的 Connected to 并不表示连接成功,因为 UDP 是无连接的,只是发送数据包,不检查是否发送成功。要看对方的终端是否收到消息。

# tcpdump

:一个网络抓包工具,可以抓取主机网络接口上收发的所有数据包。

  • 命令:

    tcpdump
            -i lo         # 监听指定网口。默认是监听第一个以太网接口 eth0 。指定 -i any 则监听所有网卡
            -Q inout      # 抓取哪个方向的数据包,可选 in、out、inout
            -c <int>      # 抓取指定数量的数据包之后,就停止 tcpdump
            -s <int>      # 每个数据包,最多抓取多少 bytes
    
            -n            # 将主机名、域名,显示成 IP 地址
            -nn           # 将端口名,显示成端口号
            -v            # 显示数据包的详细信息
            -vv           # 显示数据包更详细的信息
    
            # 过滤表达式
            host 10.0.0.1       # 只抓取 src 或 dst 地址为该主机,的数据包
            net 10.0.0.1/24     # 指定一个网段
            port 80             # 指定端口
            src 10.0.0.1        # 指定源地址。可以组合使用 src host、src net、sort port
            dst 10.0.0.1        # 指定目的地址
            tcp                 # 只抓取 TDP 协议
            udp                 # 只抓取 UDP 协议
            tcp and dst port 80 # 可以使用 and、or、not 运算符,组合多个过滤条件
    
            -w dump.pcap        # 将原始抓取信息,保存为一个二进制文件
            -r dump.pcap        # 读取文件中的抓取信息,打印到终端
    
  • 下例是对一次 HTTP 请求的抓包:

    [root@CentOS ~]# tcpdump -nn tcp and host 10.124.130.12 and dst port 80
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
    13:46:14.669786 IP 10.124.128.97.52152 > 10.124.130.12.80: Flags [S], seq 2920488928, win 29200, options [mss 1424,sackOK,TS val 3983484990 ecr 0,nop,wscale 7], length 0
    13:46:14.670038 IP 10.124.128.97.52152 > 10.124.130.12.80: Flags [.], ack 174830516, win 229, options [nop,nop,TS val 3983484990 ecr 2392282894], length 0
    13:46:14.670095 IP 10.124.128.97.52152 > 10.124.130.12.80: Flags [P.], seq 0:82, ack 1, win 229, options [nop,nop,TS val 3983484990 ecr 2392282894], length 82
    13:46:14.672466 IP 10.124.128.97.52152 > 10.124.130.12.80: Flags [.], ack 18, win 229, options [nop,nop,TS val 3983484992 ecr 2392282896], length 0
    13:46:14.672591 IP 10.124.128.97.52152 > 10.124.130.12.80: Flags [.], ack 378, win 237, options [nop,nop,TS val 3983484992 ecr 2392282897], length 0
    13:46:14.672667 IP 10.124.128.97.52152 > 10.124.130.12.80: Flags [F.], seq 82, ack 378, win 237, options [nop,nop,TS val 3983484993 ecr 2392282897], length 0
    13:46:14.672805 IP 10.124.128.97.52152 > 10.124.130.12.80: Flags [.], ack 379, win 237, options [nop,nop,TS val 3983484993 ecr 2392282897], length 0
    
    • 每行包含多个字段:时间戳 源地址 > 目的地址 Flags ... length
    • 常见的几种 TCP 数据包标志:
      [S]     # SYN 数据包
      [.]     # ACK 数据包
      [S.]    # SYN+ACK 数据包
      [P]     # PUSH 数据包
      [F]     # FIN 数据包
      [R]     # RST 数据包
      
    • 这样只能查看 HTTP 请求底层的各个 TCP 请求。如果想提取出 HTTP 请求的报文,可以将 pcap 文件导入 Wireshark 软件,在 GUI 界面中分析。

# 网速测试

# speedtest

:一个测试工具,用于测试本机到公网的网速,采用 Python 语言开发。

  • 安装:pip install speedtest-cli
  • 命令:
    speedtest-cli               # 开始测试
                  --list        # 列出所有可用的 speedtest.net 服务器
                  --server <id> # 采用指定的服务器进行测试
                  --json        # 测试结果显示成 json 格式
    
  • 例:
    [root@CentOS ~]# speedtest-cli
    Retrieving speedtest.net configuration...
    Testing from Tencent cloud computing (129.204.40.71)...   # 发现本机的公网 IP
    Retrieving speedtest.net server list...
    Selecting best server based on ping...                    # 自动选择一个延迟最低的 speedtest.net 服务器来测试
    Hosted by China Mobile Group Beijing Co.Ltd (Beijing) [1.69 km]: 50.546 ms
    Testing download speed................................................................................
    Download: 21.60 Mbit/s                                    # 下载速度
    Testing upload speed................................................................................................
    Upload: 22.35 Mbit/s                                      # 上传速度
    

# iperf

:一个测试工具,可以作为服务端、客户端运行,从而测试任意两台主机之间的 TCP/UDP 带宽。

  • 安装:yum install iperf
  • 用法:
    • 先在一个主机上让 iperf 作为服务器运行,监听 80 端口:
      iperf -s -p 80
      
    • 然后在另一个主机上让 iperf 作为客户端运行,开始测试:
      iperf -c <服务器 IP> -p 80
      

# iftop

:一个监控工具,能实时监控各 Socket 的网络流量。

  • 安装:yum install iftop

  • 用法:

    iftop         # 打开一个监控窗口
        -i eth0   # 指定要监控的网卡。默认监控第一个网卡
        -B        # 相当于 -u bytes
        -u bits|bytes|packets # 显示流量的单位。默认为 bits
        -m 1G     # 设置流量刻度的最大值。默认会自动设置
        -n        # 取消将 IP 显示成主机名、域名
        -N        # 取消将端口号显示成服务名
        -P        # 显示端口。默认只显示网络流量的收、发 IP ,不显示端口
    
        # 设置过滤器
        -f <filter>
          host 10.0.    # 只显示与指定 IP 相关的流量
          src 10.0.0.1  # 只显示指定源 IP 的流量
          dst port 22   # 只显示指定目标端口的流量
    
  • 打开 iftop 窗口之后可以输入以下命令:

    b     # 切换是否显示顶部的流量刻度
    j/k   # 下上滚动
    l     # 编辑 filter
    L     # 切换是否显示一个横向的柱状图,方便比较每行的流量大小
    n     # 切换是否将 IP 显示成主机名、域名
    p     # 切换是否显示端口号
    P     # 暂停窗口的显示
    t     # 切换每行的显示模式:只显示发流量、只显示收流量、同时显示两种流量、合并成一行流量
    T     # 增加显示一列,表示每行从建立 Socket 连接以来的总流量
    h/?   # 显示帮助页面
    
  • 例:

    [root@CentOS ~]# iftop -B
                          205MB                  410MB                  614MB                  819MB                 1.00GB
    └──────────────────────┴──────────────────────┴──────────────────────┴──────────────────────┴───────────────────────────
    10.0.0.1                                          => baidu.com                                  146Kb   110Kb   804Kb
                                                      <=                                            269Kb   204Kb   241Kb
    10.0.0.1                                          => 10.0.0.2                                   12.5Kb  10.2Kb  10.8Kb
                                                      <=                                            75.3Kb  60.5Kb  64.8Kb
    10.0.0.1                                          => 10.0.0.3                                   12.3Kb  9.86Kb  13.5Kb
                                                      <=                                            75.2Kb  60.4Kb  86.0Kb
    
    ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    TX:             cum:   1.44MB   peak:   4.91Mb                                          rates:    187Kb   143Kb   842Kb
    RX:                     693KB            614Kb                                                    420Kb   328Kb   396Kb
    TOTAL:                 2.12MB           5.51Mb                                                    608Kb   471Kb  1.21Mb
    
    • 顶部一行表示流量刻度,按 L 启用柱状图时比较有用。
    • 每行的 =>、<= 表示网卡发送、接收的流量,在底部又汇总为 TX、RX、TOTAL 三行(汇总行不受 filter 影响)。
    • cum 列表示开始执行 iftop 至今的总流量,peak 列表示这期间的每秒流量峰值。
    • 右侧的 rates 三列表示最近 2s、10s、40s 的平均每秒流量。

# HTTP 测试

# ab

:一个测试工具,原名为 Apache Benchmark 。可作为 HTTP 客户端运行,对 HTTP 服务器进行压力测试。

  • 安装:yum install httpd-tools
  • 命令:
    ab -c 100 -n 10000 <服务器 IP>    # 模拟 100 个并发数,总共发送 10000 个请求报文
    

# wrk

:一个测试工具,用于 HTTP 压测。

  • 命令:
    wrk <服务器 IP>
        -t 12                   # 模拟的线程数
        -c 400                  # 模拟的连接数
        -d 30                   # 测试的持续时间
        -H "Connection: Close"  # 测试短连接(默认是长连接)
    
  • wrk 运行结束之后会显示测试结果,主要指标为:
    • Latency :响应时间
    • Req/Sec :每个线程每秒钟完成的请求数
    • Stdev :标准差

# Postman

:一个 GUI 测试工具,便于测试 HTTP 服务器的 API 。

  • 可以将测试任务导出为 C、curl、Python 等形式的代码。
  • 可以批量执行测试任务。

# Jmeter

:一个 GUI 测试工具,提供了通用的网络测试功能,采用 Java 语言开发。

  • 可作为命令行工具使用,也提供了 GUI 界面。
  • 可测试 HTTP、FTP、MQTT 等多种通信协议,可进行功能测试、性能测试。
  • 在左侧栏制定测试计划,然后点击 run 即可执行它。
  • 测试计划中可以使用定时器等多种控件,实现丰富的控制逻辑。