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 压测 / 测试工具
  • 支持发送频率 + 发包总数配置
  • 自带帧号 + 毫秒时间戳
  • 服务端实时显示延迟、丢包、接收状态
  • 代码轻量、无第三方依赖、可直接用于项目测试
相关推荐
hanbr1 小时前
C++ 类型转换与异常处理全解析
开发语言·c++
ym_xixi1 小时前
《类和对象》—— 构造函数与析构函数总结
前端·c++·算法
洛水水1 小时前
【力扣100题】19. 排序链表 | 归并排序详解
算法·leetcode·链表
凯瑟琳.奥古斯特1 小时前
丑数II C++三指针解法(力扣264)
数据结构·c++·算法·leetcode·职场和发展
YYYing.1 小时前
【C++项目之高并发内存池 (四)】三层缓存的空间回收流程详解
c++·笔记·缓存·高并发·内存池
小小de风呀1 小时前
de风——【从零开始学C++】(六):模板初阶
开发语言·c++
j_xxx404_1 小时前
力扣算法:用栈消消乐,巧解相邻重复与退格字符串
c++·算法·leetcode
鲁邦通物联网1 小时前
架构实战:高容错分布式机器人梯控系统的电气解耦设计
机器人·机器人梯控·agv梯控·非侵入式采集·机器人乘梯·机器人自主乘梯·agv机器人梯控
Hello.Reader1 小时前
算法基础(十一)—— 递归树如何看懂分治算法的运行时间
java·算法·排序算法