多对多的线程的iperf测试-双服务器模拟

背景

我们需要模拟一个服务器作为下载服务器,然后客户端模拟大量的下载的,我们的环境可能没有那么多的机器,不是很好准备环境

模拟环境

这个我们只需要准备两台大容量的服务器,然后其中一台作为服务器,另外一台作为客户端,客户端可以生成很多虚拟的网卡,然后通过虚拟ip绑定iperf来1对1的测试

环境准备

服务器准备一个虚拟IP

ip addr add 192.168.1.5/24 dev eth0

这个最好用一个新网段,这样可以占用大量的ip

客户端生成多IP

seq 101 199 |xargs -i ip addr add 192.168.1.{}/24 dev eth0 label eth0:{}

服务器脚本

[root@lab211 iperf]# cat startiperf.sh
#!/bin/bash
# startiperf.sh
# iperf3 server 批量启动(多端口 + 实时日志)

####################################
# 配置
####################################
LOG_BASE_DIR="$(pwd)/iperf_logs"
IPERF_CMD="iperf3"

####################################
# 颜色
####################################
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

info() { echo -e "${BLUE}[INFO]${NC} $1"; }
ok()   { echo -e "${GREEN}[OK]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
err()  { echo -e "${RED}[ERR]${NC} $1"; }

####################################
# 检查环境
####################################
command -v iperf3 >/dev/null || { err "iperf3 未安装"; exit 1; }
command -v stdbuf >/dev/null || { err "stdbuf 未安装"; exit 1; }

####################################
# 读取当前配置
####################################
current_log_dir() {
    [ -f "${LOG_BASE_DIR}/current_config" ] && \
        source "${LOG_BASE_DIR}/current_config" && \
        echo "$CURRENT_LOG_DIR"
}

####################################
# 启动
####################################
start_servers() {
    local START=$1
    local END=$2

    mkdir -p "$LOG_BASE_DIR"
    TS=$(date +%Y%m%d_%H%M%S)
    LOG_DIR="${LOG_BASE_DIR}/iperf_${START}_${END}_${TS}"
    mkdir -p "$LOG_DIR"

    info "日志目录: $LOG_DIR"
    info "端口范围: ${START}-${END}"

    local ok_cnt=0

    for port in $(seq "$START" "$END"); do
        log="${LOG_DIR}/port_${port}.log"
        pidf="${LOG_DIR}/pid_${port}"

        if ss -lnt | awk '{print $4}' | grep -q ":${port}$"; then
            warn "端口 ${port} 已占用,跳过"
            continue
        fi

        echo "[`date '+%F %T'`] START iperf3 -s -p ${port}" > "$log"

        stdbuf -oL -eL iperf3 -s -p "$port" >> "$log" 2>&1 &
        pid=$!

        sleep 0.1
        if kill -0 "$pid" 2>/dev/null; then
            echo "$pid" > "$pidf"
            ok "端口 ${port} 启动成功 (PID $pid)"
            ((ok_cnt++))
        else
            err "端口 ${port} 启动失败"
        fi
    done

    cat > "${LOG_BASE_DIR}/current_config" <<EOF
CURRENT_LOG_DIR="$LOG_DIR"
START_PORT=$START
END_PORT=$END
START_TIME="$(date)"
EOF

    info "启动完成:${ok_cnt}/$((END-START+1))"
}

####################################
# 停止
####################################
stop_servers() {
    LOG_DIR=$(current_log_dir)
    [ -z "$LOG_DIR" ] && { info "没有运行实例"; return; }

    for f in "$LOG_DIR"/pid_*; do
        pid=$(cat "$f")
        kill "$pid" 2>/dev/null && ok "停止 PID $pid"
    done

    rm -f "${LOG_BASE_DIR}/current_config"
}

####################################
# 状态
####################################
status_servers() {
    LOG_DIR=$(current_log_dir)
    [ -z "$LOG_DIR" ] && { info "无运行实例"; return; }

    for f in "$LOG_DIR"/pid_*; do
        port=$(basename "$f" | cut -d_ -f2)
        pid=$(cat "$f")
        kill -0 "$pid" 2>/dev/null \
            && echo "端口 ${port}: RUNNING (PID ${pid})" \
            || echo "端口 ${port}: DEAD"
    done
}

####################################
# main
####################################
case "$1" in
    start)  start_servers "$2" "$3" ;;
    stop)   stop_servers ;;
    status) status_servers ;;
    *) echo "用法: $0 start <s> <e> | stop | status" ;;
esac

使用方法

bash  startiperf.sh  start 5101 5200

这个就是会启动100个进程,启动了5101到5200一共100个端口的iperf

客户端脚本

[root@lab212 iperf]# cat iperf-client.sh
#!/bin/bash
# 文件名: iperf_client.sh
# 功能: 并发iperf客户端测试工具(客户端IP与服务器端口一对一映射)
# 用法:
#   启动: ./iperf_client.sh start 服务器IP 服务器端口开始 服务器端口结束 客户端IP开始 客户端IP结束 测试时间 [并发数]
#   停止: ./iperf_client.sh stop
#   状态: ./iperf_client.sh status
# 示例:
#   ./iperf_client.sh start 192.168.1.5 5101 5109 192.168.1.101 192.168.1.109 60 5
#   ./iperf_client.sh stop
#   ./iperf_client.sh status

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
NC='\033[0m' # No Color

# 打印函数
print_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
print_header() { echo -e "${PURPLE}$1${NC}"; }

# 检查参数
check_start_args() {
    if [ $# -lt 7 ] || [ $# -gt 8 ]; then
        print_error "启动参数错误"
        echo "用法: $0 start 服务器IP 服务器端口开始 服务器端口结束 客户端IP开始 客户端IP结束 测试时间 [并发数]"
        echo "示例: $0 start 192.168.1.5 5101 5109 192.168.1.101 192.168.1.109 60 5"
        echo "说明: 每个客户端IP对应一个服务器端口,一对一并发测试"
        exit 1
    fi
}

# 检查iperf
check_iperf() {
    if ! command -v iperf3 &> /dev/null; then
        if ! command -v iperf &> /dev/null; then
            print_error "未找到iperf或iperf3"
            exit 1
        fi
        IPERF="iperf"
    else
        IPERF="iperf3"
    fi
    print_info "使用iperf命令: $IPERF"
}

# IP递增函数
next_ip() {
    echo $1 | awk -F. '{
        if ($4 < 255) {
            $4++
        } else if ($3 < 255) {
            $4=0
            $3++
        } else if ($2 < 255) {
            $4=0; $3=0
            $2++
        } else if ($1 < 255) {
            $4=0; $3=0; $2=0
            $1++
        }
        print $1"."$2"."$3"."$4
    }'
}

# 生成IP列表
generate_ip_list() {
    local start_ip="$1"
    local end_ip="$2"
    local ip_list=()
    local current_ip="$start_ip"

    while true; do
        ip_list+=("$current_ip")

        if [ "$current_ip" = "$end_ip" ]; then
            break
        fi

        current_ip=$(next_ip "$current_ip")
    done

    echo "${ip_list[@]}"
}

# 验证IP和端口数量匹配
validate_mapping() {
    local server_port_start="$1"
    local server_port_end="$2"
    local client_start="$3"
    local client_end="$4"

    # 计算端口数量
    local port_count=$((server_port_end - server_port_start + 1))

    # 计算IP数量
    local start_ip_int=$(echo "$client_start" | awk -F. '{print $1 * 256^3 + $2 * 256^2 + $3 * 256 + $4}')
    local end_ip_int=$(echo "$client_end" | awk -F. '{print $1 * 256^3 + $2 * 256^2 + $3 * 256 + $4}')
    local ip_count=$((end_ip_int - start_ip_int + 1))

    if [ $port_count -ne $ip_count ]; then
        print_error "端口数量($port_count)与客户端IP数量($ip_count)不匹配!"
        print_error "必须一对一映射,请确保数量相同"
        return 1
    fi

    return 0
}

# 启动测试
start_test() {
    local server_ip="$1"
    local server_port_start="$2"
    local server_port_end="$3"
    local client_start="$4"
    local client_end="$5"
    local duration="$6"
    local parallel="${7:-1}"  # 默认并发数为1

    print_header "====== 启动iperf客户端测试 ======"

    # 验证IP和端口数量匹配
    if ! validate_mapping "$server_port_start" "$server_port_end" "$client_start" "$client_end"; then
        exit 1
    fi

    # 检查并创建日志目录
    LOG_DIR="iperf_client_$(date +%Y%m%d_%H%M%S)"
    PID_DIR="$LOG_DIR/pids"
    mkdir -p "$PID_DIR"

    CONFIG_FILE="$LOG_DIR/config.txt"
    SUMMARY_FILE="$LOG_DIR/summary.txt"
    RUNNING_FILE="$LOG_DIR/running.txt"
    PORT_MAP_FILE="$LOG_DIR/port_map.txt"

    # 生成客户端IP列表
    print_info "生成客户端IP列表..."
    local client_ips=($(generate_ip_list "$client_start" "$client_end"))
    local client_count=${#client_ips[@]}

    # 生成服务器端口列表
    local server_ports=()
    for port in $(seq "$server_port_start" "$server_port_end"); do
        server_ports+=("$port")
    done

    # 保存配置
    {
        echo "服务器IP: $server_ip"
        echo "服务器端口范围: $server_port_start - $server_port_end"
        echo "客户端IP范围: $client_start - $client_end"
        echo "客户端数量: $client_count"
        echo "测试时长: ${duration}秒"
        echo "并发数: $parallel"
        echo "开始时间: $(date)"
        echo "日志目录: $LOG_DIR"
        echo "进程目录: $PID_DIR"
        echo ""
        echo "端口映射关系:"
    } > "$CONFIG_FILE"

    # 显示配置
    print_info "配置信息:"
    print_info "  服务器IP: $server_ip"
    print_info "  服务器端口: $server_port_start - $server_port_end"
    print_info "  客户端IP: $client_start - $client_end"
    print_info "  客户端数量: $client_count"
    print_info "  测试时长: ${duration}秒"
    print_info "  并发数: $parallel"
    print_info "  日志目录: $LOG_DIR"

    # 显示端口映射
    print_info ""
    print_info "端口映射关系:"

    # 创建映射数组
    local mapping_index=0
    for ((i=0; i<client_count; i++)); do
        local client_ip="${client_ips[i]}"
        local server_port="${server_ports[i]}"

        print_info "  客户端 $client_ip -> 服务器 $server_ip:$server_port"
        echo "  $client_ip -> $server_ip:$server_port" >> "$CONFIG_FILE"
        echo "$client_ip:$server_port" >> "$PORT_MAP_FILE"
    done

    # 估计总时间
    local estimated_time=$(( (client_count + parallel - 1) / parallel * duration ))
    print_warning "预计总时间: ${estimated_time}秒 (~$(($estimated_time/60))分钟)"

    read -p "是否开始测试? (y/N): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        print_info "用户取消操作"
        rm -rf "$LOG_DIR"
        exit 0
    fi

    # 开始时间
    local start_time=$(date +%s)
    echo "$start_time" > "$LOG_DIR/start_time.txt"
    echo "$server_ip" > "$LOG_DIR/server_ip.txt"

    # 计数器
    local test_count=0
    local success_count=0
    local fail_count=0

    # 启动信号量控制
    if [ "$parallel" -gt 1 ]; then
        # 创建命名管道作为信号量
        SEMAPHORE="/tmp/iperf_semaphore_$$"
        mkfifo "$SEMAPHORE"

        # 初始化信号量
        for ((i=0; i<parallel; i++)); do
            echo > "$SEMAPHORE" &
        done

        # 为信号量打开文件描述符
        exec 3<> "$SEMAPHORE"
    fi

    # 启动测试(一对一映射)
    for ((i=0; i<client_count; i++)); do
        test_count=$((test_count + 1))
        local client_ip="${client_ips[i]}"
        local server_port="${server_ports[i]}"

        # 并发控制
        if [ "$parallel" -gt 1 ]; then
            # 获取信号量
            read -u 3
        fi

        # 执行单个测试(后台运行)
        run_single_test "$server_ip" "$server_port" "$client_ip" "$duration" "$LOG_DIR" "$PID_DIR" "$test_count" "$client_count" &

        # 记录进程
        local pid=$!
        echo "$pid:$client_ip:$server_port" >> "$RUNNING_FILE"
        echo "$pid" > "$PID_DIR/$pid.pid"

        # 控制并发数量
        if [ "$parallel" -gt 1 ]; then
            # 后台释放信号量
            {
                wait $pid
                echo >&3
            } &
        fi

        print_info "启动测试 [$test_count/$client_count]: 客户端 $client_ip -> 服务器 $server_ip:$server_port (PID: $pid)"

        # 短暂延迟避免同时启动过多
        sleep 0.1
    done

    # 等待所有后台进程
    if [ "$parallel" -gt 1 ]; then
        # 等待所有信号量释放
        for ((i=0; i<parallel; i++)); do
            read -u 3
        done
        exec 3<&-
        rm -f "$SEMAPHORE"
    else
        # 串行等待
        wait
    fi

    # 结束时间
    local end_time=$(date +%s)
    local total_time=$((end_time - start_time))

    # 统计结果
    if [ -f "$LOG_DIR/results.txt" ]; then
        success_count=$(grep -c "成功" "$LOG_DIR/results.txt" 2>/dev/null || echo 0)
        fail_count=$(grep -c "失败" "$LOG_DIR/results.txt" 2>/dev/null || echo 0)
    fi

    # 生成报告
    print_header "====== 测试完成 ======"
    print_info "完成时间: $(date)"
    print_info "总耗时: ${total_time}秒"
    print_info "总测试数: $test_count"
    print_info "成功: $success_count"
    print_info "失败: $fail_count"

    if [ $test_count -gt 0 ]; then
        local success_rate=$(echo "scale=2; $success_count * 100 / $test_count" | bc)
        print_success "成功率: ${success_rate}%"
    fi

    print_info "日志目录: $LOG_DIR"

    # 生成详细报告
    generate_report "$LOG_DIR" "$test_count" "$success_count" "$fail_count" "$start_time" "$end_time"
}

# 执行单个测试
run_single_test() {
    local server_ip="$1"
    local server_port="$2"
    local client_ip="$3"
    local duration="$4"
    local log_dir="$5"
    local pid_dir="$6"
    local test_num="$7"
    local total_tests="$8"

    local log_file="$log_dir/client_${client_ip}_port_${server_port}.log"
    local summary_file="$log_dir/summary.txt"

    # 记录开始
    {
        echo "========================================"
        echo "测试 [$test_num/$total_tests]"
        echo "时间: $(date '+%Y-%m-%d %H:%M:%S')"
        echo "客户端IP: $client_ip"
        echo "服务器IP: $server_ip"
        echo "服务器端口: $server_port"
        echo "时长: ${duration}秒"
        echo "----------------------------------------"
    } > "$log_file"

    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始测试: 客户端 $client_ip -> 服务器 $server_ip:$server_port" >> "$summary_file"

    # 执行iperf测试
    local cmd="$IPERF -c $server_ip -p $server_port -R -B $client_ip -t $duration"
    echo "执行命令: $cmd" >> "$log_file"
    echo "" >> "$log_file"

    if timeout $((duration + 10)) $cmd >> "$log_file" 2>&1; then
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✓ 测试成功: 客户端 $client_ip -> 服务器 $server_ip:$server_port" >> "$summary_file"
        echo "成功" >> "$log_dir/results.txt"
        echo -e "\n✅ 测试成功!" >> "$log_file"
    else
        local exit_code=$?
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✗ 测试失败: 客户端 $client_ip -> 服务器 $server_ip:$server_port (退出码: $exit_code)" >> "$summary_file"
        echo "失败" >> "$log_dir/results.txt"
        echo -e "\n❌ 测试失败! 退出码: $exit_code" >> "$log_file"
    fi

    # 清理PID文件
    rm -f "$pid_dir/$$.pid" 2>/dev/null
}

# 停止测试
stop_test() {
    print_header "====== 停止iperf测试 ======"

    # 查找最近的日志目录
    local latest_dir=$(ls -d iperf_client_* 2>/dev/null | sort -r | head -1)

    if [ -z "$latest_dir" ]; then
        print_error "未找到运行中的iperf测试"
        return 1
    fi

    print_info "找到测试目录: $latest_dir"

    # 检查PID目录
    local pid_dir="$latest_dir/pids"

    # 停止所有记录的进程
    local stop_count=0

    if [ -f "$latest_dir/running.txt" ]; then
        while IFS=':' read -r pid client_ip port; do
            if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
                print_info "停止进程: $pid (客户端: $client_ip, 端口: $port)"
                kill "$pid" 2>/dev/null
                ((stop_count++))
            fi
        done < "$latest_dir/running.txt"
    fi

    # 停止所有iperf客户端进程
    local iperf_pids=$(pgrep -f "iperf.*-c")
    for pid in $iperf_pids; do
        if kill -0 "$pid" 2>/dev/null; then
            print_info "停止iperf进程: $pid"
            kill "$pid" 2>/dev/null
            ((stop_count++))
        fi
    done

    # 等待进程结束
    sleep 2

    # 强制终止残留进程
    local remaining=$(pgrep -f "iperf.*-c")
    if [ -n "$remaining" ]; then
        print_warning "强制终止残留进程..."
        for pid in $remaining; do
            kill -9 "$pid" 2>/dev/null
            ((stop_count++))
        done
    fi

    # 清理PID目录
    if [ -d "$pid_dir" ]; then
        rm -rf "$pid_dir"
    fi

    print_success "已停止 $stop_count 个进程"

    # 记录停止时间
    echo "停止时间: $(date)" >> "$latest_dir/config.txt"
    echo "测试被手动停止" >> "$latest_dir/summary.txt"

    print_info "测试已停止,日志保存在: $latest_dir"
}

# 查看状态
show_status() {
    print_header "====== iperf测试状态 ======"

    # 查找最新的测试目录
    local latest_dir=$(ls -d iperf_client_* 2>/dev/null | sort -r | head -1)

    if [ -z "$latest_dir" ]; then
        print_info "没有运行中的iperf测试"
        return 0
    fi

    print_info "测试目录: $latest_dir"

    # 读取配置
    if [ -f "$latest_dir/config.txt" ]; then
        echo ""
        print_info "配置信息:"
        grep -E "^(服务器IP|服务器端口范围|客户端IP范围|客户端数量|测试时长|并发数|开始时间):" "$latest_dir/config.txt" | while read line; do
            print_info "  $line"
        done
    fi

    # 检查是否在运行
    local running_count=0
    if [ -f "$latest_dir/running.txt" ]; then
        while IFS=':' read -r pid client_ip port; do
            if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
                ((running_count++))
            fi
        done < "$latest_dir/running.txt"
    fi

    # 检查iperf进程
    local iperf_processes=$(pgrep -c -f "iperf.*-c" 2>/dev/null || echo 0)

    if [ $running_count -gt 0 ] || [ $iperf_processes -gt 0 ]; then
        print_success "状态: 运行中"
        print_info "  活动进程: $running_count"
        print_info "  iperf进程: $iperf_processes"

        # 显示正在运行的测试
        if [ -f "$latest_dir/running.txt" ] && [ $running_count -gt 0 ]; then
            echo ""
            print_info "运行中的测试:"
            while IFS=':' read -r pid client_ip port; do
                if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
                    print_info "  PID $pid: 客户端 $client_ip -> 服务器端口 $port"
                fi
            done < "$latest_dir/running.txt"
        fi

        # 显示进度
        if [ -f "$latest_dir/results.txt" ]; then
            local completed=$(wc -l < "$latest_dir/results.txt" 2>/dev/null || echo 0)
            if [ -f "$latest_dir/config.txt" ]; then
                local total=$(grep "客户端数量:" "$latest_dir/config.txt" | awk '{print $2}')
                if [ -n "$total" ] && [ "$total" -gt 0 ]; then
                    local progress=$((completed * 100 / total))
                    print_info "  进度: $completed/$total (${progress}%)"
                fi
            fi
        fi
    else
        print_info "状态: 已停止"

        # 显示统计结果
        if [ -f "$latest_dir/results.txt" ]; then
            local success=$(grep -c "成功" "$latest_dir/results.txt" 2>/dev/null || echo 0)
            local fail=$(grep -c "失败" "$latest_dir/results.txt" 2>/dev/null || echo 0)
            local total=$((success + fail))

            if [ $total -gt 0 ]; then
                echo ""
                print_info "测试结果:"
                print_info "  总测试数: $total"
                print_info "  成功: $success"
                print_info "  失败: $fail"

                local success_rate=$(echo "scale=2; $success * 100 / $total" | bc)
                print_success "  成功率: ${success_rate}%"
            fi
        fi

        # 显示映射关系
        if [ -f "$latest_dir/port_map.txt" ]; then
            echo ""
            print_info "端口映射:"
            while IFS=':' read -r client_ip server_port; do
                local result=""
                if [ -f "$latest_dir/results.txt" ]; then
                    local test_result=$(grep -q "成功" "$latest_dir/results.txt" 2>/dev/null && echo "✓" || echo "✗")
                    result=" $test_result"
                fi
                print_info "  客户端 $client_ip -> 端口 $server_port$result"
            done < "$latest_dir/port_map.txt"
        fi
    fi

    echo ""
    print_info "命令:"
    print_info "  $0 stop     # 停止测试"
    print_info "  $0 status   # 查看状态"
    print_info "  $0 logs     # 查看日志"
}

# 查看日志
show_logs() {
    local latest_dir=$(ls -d iperf_client_* 2>/dev/null | sort -r | head -1)

    if [ -z "$latest_dir" ]; then
        print_error "没有找到测试日志"
        return 1
    fi

    print_header "====== 测试日志 ======"
    print_info "日志目录: $latest_dir"

    echo ""
    print_info "日志文件:"
    ls -1 "$latest_dir"/*.log 2>/dev/null | head -10 | while read log; do
        local size=$(du -h "$log" | cut -f1)
        local lines=$(wc -l < "$log" 2>/dev/null || echo 0)
        print_info "  $(basename $log) (${size}, ${lines}行)"
    done

    local log_count=$(ls -1 "$latest_dir"/*.log 2>/dev/null | wc -l)
    print_info "日志文件总数: $log_count"

    echo ""
    print_info "查看日志示例:"
    print_info "  tail -f $latest_dir/client_*.log"
    print_info "  grep -l '失败' $latest_dir/*.log"
}

# 生成报告
generate_report() {
    local log_dir="$1"
    local total="$2"
    local success="$3"
    local fail="$4"
    local start_time="$5"
    local end_time="$6"

    local report_file="$log_dir/report.txt"

    {
        echo "iperf客户端测试报告"
        echo "===================="
        echo ""
        echo "测试摘要"
        echo "--------"
        echo "开始时间: $(date -d @$start_time)"
        echo "结束时间: $(date -d @$end_time)"
        echo "总耗时: $((end_time - start_time))秒"
        echo ""
        echo "测试统计"
        echo "--------"
        echo "总测试数: $total"
        echo "成功数: $success"
        echo "失败数: $fail"

        if [ $total -gt 0 ]; then
            local success_rate=$(echo "scale=2; $success * 100 / $total" | bc)
            echo "成功率: ${success_rate}%"
        fi
        echo ""
        echo "配置信息"
        echo "--------"
        grep -v "^$" "$log_dir/config.txt" | head -20
        echo ""
        echo "文件信息"
        echo "--------"
        echo "日志目录: $log_dir"
        echo "日志文件: $(ls -1 $log_dir/*.log 2>/dev/null | wc -l)"
        echo "配置文件: $log_dir/config.txt"
        echo "摘要文件: $log_dir/summary.txt"
        echo "报告文件: $report_file"
    } > "$report_file"

    print_info "详细报告: $report_file"
}

# 显示使用帮助
show_help() {
    cat << EOF
并发iperf客户端测试工具(客户端IP与服务器端口一对一映射)
版本: 4.0

用法:
  $0 start 服务器IP 服务器端口开始 服务器端口结束 客户端IP开始 客户端IP结束 测试时间 [并发数]
  $0 stop
  $0 status
  $0 logs
  $0 help

示例:
  # 启动测试 (并发5个)
  $0 start 192.168.1.5 5101 5109 192.168.1.101 192.168.1.109 60 5

  # 启动测试 (串行)
  $0 start 192.168.1.5 5101 5109 192.168.1.101 192.168.1.109 60

  # 停止测试
  $0 stop

  # 查看状态
  $0 status

  # 查看日志
  $0 logs

说明:
  - 客户端IP与服务器端口一对一映射
  - 例如: 客户端192.168.1.101 -> 服务器192.168.1.5:5101
  - 例如: 客户端192.168.1.102 -> 服务器192.168.1.5:5102
  - 必须保持客户端IP数量与服务器端口数量相同
  - 并发数可选,默认为1(串行)
EOF
}

# 主函数
main() {
    case "$1" in
        start)
            check_iperf
            check_start_args "$@"
            shift
            start_test "$@"
            ;;
        stop)
            stop_test
            ;;
        status)
            show_status
            ;;
        logs)
            show_logs
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            if [ $# -eq 0 ]; then
                show_help
            else
                print_error "未知命令: $1"
                show_help
                exit 1
            fi
            ;;
    esac
}

# 运行主函数
main "$@"

使用方法

./iperf-client.sh start  192.168.1.5 5101 5200 192.168.1.101 192.168.1.200 60

这个固定使用方法,指定服务器的ip 192.168.1.5 端口范围是5101到5200 客户端绑定的ip是192.168.1.101到192.168.1.200,指定测试时间为60秒

执行后,就可以模拟出一个100个客户端并发的去访问服务器的情况,后面就结合限速脚本观察是否符合自己的预期情况

日志查看

可以在服务端查看运行的日志情况,里面可以看是否有丢包,速度是否准

erver listening on 5200
-----------------------------------------------------------
Accepted connection from 192.168.1.200, port 32777
[  5] local 192.168.1.5 port 5200 connected to 192.168.1.200 port 40202
[ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
[  5]   0.00-1.00   sec  10.1 MBytes  84.3 Mbits/sec    0    594 KBytes
[  5]   1.00-2.00   sec  9.07 MBytes  76.1 Mbits/sec    0    594 KBytes
[  5]   2.00-3.00   sec  9.20 MBytes  77.1 Mbits/sec    0    594 KBytes
[  5]   3.00-4.00   sec  9.07 MBytes  76.1 Mbits/sec    0    594 KBytes
[  5]   4.00-5.00   sec  9.20 MBytes  77.1 Mbits/sec    0    594 KBytes
[  5]   5.00-6.00   sec  9.07 MBytes  76.1 Mbits/sec    0    594 KBytes
[  5]   6.00-7.00   sec  9.07 MBytes  76.1 Mbits/sec    0    594 KBytes
[  5]   7.00-8.00   sec  9.20 MBytes  77.1 Mbits/sec    0    594 KBytes
[  5]   8.00-9.00   sec  9.07 MBytes  76.1 Mbits/sec    0    594 KBytes
[  5]   9.00-10.00  sec  9.20 MBytes  77.2 Mbits/sec    0    594 KBytes
[  5]  10.00-11.00  sec  9.07 MBytes  76.1 Mbits/sec    0    594 KBytes
[root@lab211 iperf]# cat iperf_logs/iperf_5101_5200_20260117_135719/port_5*
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

武汉磨磨

打赏是写出更好教程的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值