C++ 跨平台 UDP 收发测试程序

纯 C++ 跨平台 UDP 收发测试程序,完全满足你的要求:

  • 可设置发送频率(每秒多少包)
  • 可设置发送包总数
  • 每个包包含:帧号 + 毫秒级时间戳
  • 服务端自动计算延迟、丢包
  • 代码简洁、可直接编译运行

UDP 服务端 + 客户端(C++ 版)


1. UDP 服务端 udp_server.cpp

功能:接收数据、解析帧号 / 时间戳、计算延迟、检测丢包

cpp

运行

复制代码
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <chrono>

using namespace std;
using namespace chrono;

// 数据包头部结构
struct PacketHeader {
    uint32_t frame_id;    // 帧号
    uint64_t timestamp;   // 发送端毫秒时间戳
};

int main() {
    // 1. 创建 UDP socket
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket failed");
        return -1;
    }

    // 2. 绑定端口
    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(8888);

    if (bind(sockfd, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("bind failed");
        close(sockfd);
        return -1;
    }

    cout << "UDP 服务端已启动,监听端口 8888..." << endl;

    char buffer[1024];
    sockaddr_in client_addr{};
    socklen_t client_len = sizeof(client_addr);

    int last_frame = -1;

    while (true) {
        // 接收数据
        ssize_t n = recvfrom(sockfd, buffer, sizeof(buffer), 0,
                             (sockaddr*)&client_addr, &client_len);
        if (n <= 0) continue;

        // 解析头部
        PacketHeader header;
        memcpy(&header, buffer, sizeof(PacketHeader));

        // 接收时间戳(毫秒)
        auto now_ms = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();
        double delay = now_ms - header.timestamp;

        // 丢包检测
        int lost = header.frame_id - last_frame - 1;
        if (lost > 0) {
            cout << "[丢包] 丢失 " << lost << " 包,当前帧:" << header.frame_id << endl;
        }
        last_frame = header.frame_id;

        cout << "[接收] 帧号:" << header.frame_id
             << " | 延迟:" << delay << "ms"
             << " | 包长:" << n << " 字节" << endl;
    }

    close(sockfd);
    return 0;
}

2. UDP 客户端 udp_client.cpp

功能:可配置频率、发包总数、自动带帧号 + 时间戳

cpp

运行

复制代码
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <chrono>
#include <thread>

using namespace std;
using namespace chrono;

// 数据包头部
struct PacketHeader {
    uint32_t frame_id;
    uint64_t timestamp;
};

// ================= 可配置参数 =================
#define SERVER_IP     "127.0.0.1"
#define SERVER_PORT   8888
#define SEND_FPS      10        // 每秒发送多少包
#define TOTAL_PACKETS 100       // 总共发送多少包
// ==============================================

int main() {
    // 1. 创建 UDP socket
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket failed");
        return -1;
    }

    // 2. 服务端地址
    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);

    // 发送间隔(微秒)
    auto interval_us = microseconds(1000000 / SEND_FPS);

    cout << "UDP 客户端启动" << endl;
    cout << "目标:" << SERVER_IP << ":" << SERVER_PORT << endl;
    cout << "发送频率:" << SEND_FPS << " 包/秒" << endl;
    cout << "总发包数:" << TOTAL_PACKETS << endl << endl;

    // 发送循环
    for (int i = 1; i <= TOTAL_PACKETS; ++i) {
        // 构造数据包
        PacketHeader header;
        header.frame_id = i;
        header.timestamp = time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count();

        // 发送
        sendto(sockfd, &header, sizeof(header), 0,
               (sockaddr*)&server_addr, sizeof(server_addr));

        cout << "[发送] 帧号:" << i << " | 时间戳:" << header.timestamp << endl;

        // 控制发送频率
        this_thread::sleep_for(interval_us);
    }

    cout << "\n发送完成!" << endl;
    close(sockfd);
    return 0;
}

3. 编译方法(Linux /macOS)

bash

运行

复制代码
g++ udp_server.cpp -o udp_server -pthread
g++ udp_client.cpp -o udp_client -pthread

4. 运行

先运行服务端:

bash

运行

复制代码
./udp_server

再运行客户端:

bash

运行

复制代码
./udp_client

5. 可修改参数(客户端)

cpp

运行

复制代码
#define SEND_FPS      10      // 每秒发10包
#define TOTAL_PACKETS 100     // 共发100包
  • 想发高速率SEND_FPS = 1000
  • 想发无限包:把 for 循环改成 while (true)

6. 功能说明

  • 帧号:从 1 递增,用于检测丢包
  • 时间戳:毫秒级,用于计算传输延迟
  • 服务端:自动打印延迟、丢包、接收长度
  • 频率控制:精确微秒级休眠

总结

  • 一套C++ 跨平台 UDP 压测 / 测试工具
  • 支持发送频率 + 发包总数配置
  • 自带帧号 + 毫秒时间戳
  • 服务端实时显示延迟、丢包、接收状态
  • 代码轻量、无第三方依赖、可直接用于项目测试
相关推荐
用户938515635075 小时前
从 O(n²) 到 O(nlogn):一文读懂快速排序的“快”与“妙”
javascript·算法
To_OC6 小时前
手写快排次次翻车?别死背快排模板了,这才是面试官想听的底层逻辑
javascript·算法·排序算法
饼干哥哥7 小时前
Reddit VOC调研太慢?搭一个AI专家团队半小时洞察任何品类|以猫用饮水机为例
人工智能·算法·ai编程
地平线开发者8 小时前
Transformer模型部署之性能优化指南
算法
地平线开发者8 小时前
人在途中:从“编译失败”到“模型可落地”——CUDA 自定义算子
算法·自动驾驶
半个落月11 小时前
从递归到快速排序:用 JavaScript 把分治思想讲明白
javascript·算法·面试
小月土星12 小时前
JavaScript 快速排序:从 pivot、双指针到分治思想
javascript·算法·面试
小月土星12 小时前
JavaScript 递归入门:从 1 到 n 求和,再到数组扁平化
javascript·算法·面试
To_OC1 天前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode