news 2026/4/8 16:38:15

NS3仿真——sixth

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
NS3仿真——sixth

sixth是一个完整的TCP拥塞控制算法对比工具,对比三种算法:Cubic、NewReno、Vegas。

一、代码整体架构

1.1 头文件引入

#include "ns3/applications-module.h" // 应用程序模块(UDP/TCP应用) #include "ns3/core-module.h" // 核心模块(时间、事件调度等) #include "ns3/internet-module.h" // 网络协议栈模块(TCP/IP) #include "ns3/network-module.h" // 网络设备模块 #include "ns3/point-to-point-module.h"// 点对点链路模块 #include <fstream> // 文件流操作 #include <iostream> // 输入输出流 #include <vector> // 动态数组容器 #include <map> // 关联数组容器 #include <iomanip> // 输出格式控制 #include <algorithm> // 算法函数(排序等)

二、数据结构设计

2.1 AlgorithmStats结构体 - 算法统计信息

struct AlgorithmStats { std::string name; // 算法名称 std::vector<double> timePoints; // 时间点数组 std::vector<uint32_t> cwndValues; // 对应时间的CWND值数组 double startTime; // 第一个数据点时间 double endTime; // 最后一个数据点时间 uint32_t maxCwnd; // 最大CWND值 uint32_t minCwnd; // 最小CWND值 double avgCwnd; // 平均CWND值 double finalCwnd; // 最终CWND值 double growthRate; // 增长率(bytes/s) int dataPoints; // 数据点数量 // 构造函数 AlgorithmStats() : name(""), startTime(0), endTime(0), maxCwnd(0), minCwnd(UINT32_MAX), avgCwnd(0), finalCwnd(0), growthRate(0), dataPoints(0) {} AlgorithmStats(const std::string& n) : name(n), startTime(0), endTime(0), maxCwnd(0), minCwnd(UINT32_MAX), avgCwnd(0), finalCwnd(0), growthRate(0), dataPoints(0) {} // 添加数据点的方法 void AddDataPoint(double time, uint32_t cwnd) { timePoints.push_back(time); // 记录时间 cwndValues.push_back(cwnd); // 记录CWND值 if (dataPoints == 0) { startTime = time; // 设置开始时间 } endTime = time; // 更新结束时间 maxCwnd = std::max(maxCwnd, cwnd); // 更新最大值 minCwnd = std::min(minCwnd, cwnd); // 更新最小值 finalCwnd = cwnd; // 更新最终值 dataPoints++; // 数据点计数 // 计算平均CWND double sum = 0; for (uint32_t val : cwndValues) { sum += val; } avgCwnd = sum / cwndValues.size(); // 计算增长率(基于最近10个点) if (cwndValues.size() >= 10) { double recentGrowth = 0; for (size_t i = cwndValues.size() - 10; i < cwndValues.size() - 1; i++) { double timeDiff = timePoints[i+1] - timePoints[i]; if (timeDiff > 0) { recentGrowth += (cwndValues[i+1] - cwndValues[i]) / timeDiff; } } growthRate = recentGrowth / 9.0; // 取平均增长率 } } };

2.2 全局数据结构

// 全局存储算法统计数据 std::map<std::string, AlgorithmStats> algorithmStats;

三、回调函数设计

3.1 Cubic算法的CWND变化回调

static void CwndChangeCubic(uint32_t oldCwnd, uint32_t newCwnd) { double currentTime = Simulator::Now().GetSeconds(); algorithmStats["Cubic"].AddDataPoint(currentTime, newCwnd); static double lastPrintTime = 0; // 静态变量,记录上次打印时间 if (currentTime - lastPrintTime >= 2.0) { // 每2秒打印一次 std::cout << std::fixed << std::setprecision(2) << "Cubic @ " << currentTime << "s: " << "CWND=" << newCwnd << " bytes (" << std::setprecision(1) << newCwnd/1024.0 << " KB)" << std::endl; lastPrintTime = currentTime; } }

3.2 NewReno和Vegas的回调

// NewReno回调(结构相同,输出名称不同) static void CwndChangeNewReno(uint32_t oldCwnd, uint32_t newCwnd) { // 同上,但操作algorithmStats["NewReno"] } // Vegas回调 static void CwndChangeVegas(uint32_t oldCwnd, uint32_t newCwnd) { // 同上,但操作algorithmStats["Vegas"] }

四、自定义应用类 TcpCwndApp

4.1 类定义

class TcpCwndApp : public Application // 继承自ns3::Application { public: TcpCwndApp(); virtual ~TcpCwndApp(); void Setup(Ptr<Socket> socket, Address address, uint32_t packetSize, DataRate dataRate); // 配置应用参数 private: virtual void StartApplication(void); // 应用启动 virtual void StopApplication(void); // 应用停止 void SendPacket(void); // 发送单个数据包 // 成员变量 Ptr<Socket> m_socket; // TCP Socket Address m_peer; // 目标地址 uint32_t m_packetSize; // 数据包大小 DataRate m_dataRate; // 发送速率 EventId m_sendEvent; // 发送事件ID bool m_running; // 运行状态标志 };

4.2 应用工作流程

void TcpCwndApp::SendPacket(void) { // 1. 创建数据包 Ptr<Packet> packet = Create<Packet>(m_packetSize); // 2. 发送数据包 m_socket->Send(packet); // 3. 如果还在运行,安排下一个发送事件 if (m_running) { // 计算下一个包的发送时间间隔 Time tNext(Seconds(m_packetSize * 8 / static_cast<double>(m_dataRate.GetBitRate()))); m_sendEvent = Simulator::Schedule(tNext, &TcpCwndApp::SendPacket, this); } }

五、核心仿真函数 RunAlgorithmSimulation

5.1 函数结构

void RunAlgorithmSimulation(std::string algorithmName, // 算法名称 std::string tcpType, // TCP类型字符串 Callback<void, uint32_t, uint32_t> cwndCallback) // 回调函数

5.2 详细步骤分析

// 初始化统计信息 algorithmStats[algorithmName] = AlgorithmStats(algorithmName);、 // 设置TCP算法类型 Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue(tcpType)); // 特别配置Vegas参数 if (algorithmName == "Vegas") { Config::SetDefault("ns3::TcpVegas::Alpha", UintegerValue(2)); Config::SetDefault("ns3::TcpVegas::Beta", UintegerValue(4)); Config::SetDefault("ns3::TcpVegas::Gamma", UintegerValue(1)); } // 创建节点 NodeContainer nodes; nodes.Create(2); // 创建链路 - 为Vegas设置不同条件 PointToPointHelper pointToPoint; if (algorithmName == "Vegas") { pointToPoint.SetDeviceAttribute("DataRate", StringValue("3Mbps")); pointToPoint.SetChannelAttribute("Delay", StringValue("15ms")); } else { pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps")); pointToPoint.SetChannelAttribute("Delay", StringValue("2ms")); } // 安装协议栈 InternetStackHelper stack; stack.Install(nodes); // 分配IP地址 Ipv4AddressHelper address; address.SetBase("10.1.1.0", "255.255.255.252"); Ipv4InterfaceContainer interfaces = address.Assign(devices); // 创建socket并连接回调 Ptr<Socket> tcpSocket = Socket::CreateSocket(nodes.Get(0), TcpSocketFactory::GetTypeId()); tcpSocket->TraceConnectWithoutContext("CongestionWindow", cwndCallback); // 创建自定义发送应用 Ptr<TcpCwndApp> app = CreateObject<TcpCwndApp>(); app->Setup(tcpSocket, sinkAddress, 1024, DataRate("1Mbps")); nodes.Get(0)->AddApplication(app); app->SetStartTime(Seconds(1.0)); app->SetStopTime(Seconds(25.0)); // 创建接收端 PacketSinkHelper sink("ns3::TcpSocketFactory", InetSocketAddress(Ipv4Address::GetAny(), sinkPort)); ApplicationContainer sinkApps = sink.Install(nodes.Get(1)); sinkApps.Start(Seconds(0.0)); sinkApps.Stop(Seconds(25.0)); // 运行仿真 Simulator::Stop(Seconds(25)); Simulator::Run(); Simulator::Destroy();

六、结果分析和展示函数

void PrintComparisonTable() { // 打印表头 std::cout << "\n" << std::string(80, '=') << std::endl; std::cout << " TCP CONGESTION CONTROL ALGORITHMS COMPARISON" << std::endl; // 打印网络条件说明 std::cout << " Network Conditions: 5Mbps bandwidth, 2ms delay" << std::endl; std::cout << " Application: 1Mbps data rate, 1024 byte packets" << std::endl; // 打印表头和表格数据 std::cout << std::left << std::setw(12) << "Algorithm" << std::setw(12) << "Data Pts" << std::setw(12) << "Duration(s)" << std::setw(15) << "Max CWND(KB)" << ... << std::endl; } void PrintPerformanceRankings() { // 1. 按最大CWND排名 std::vector<std::pair<std::string, double>> maxCwndRanking; for (const auto& pair : algorithmStats) { maxCwndRanking.push_back({pair.first, pair.second.maxCwnd}); } std::sort(maxCwndRanking.begin(), maxCwndRanking.end(), [](const auto& a, const auto& b) { return a.second > b.second; }); // 2. 按平均CWND排名 // 3. 按增长率排名 // 4. 综合评分 }

七、主函数 main

int main(int argc, char *argv[]) { // 1. 打印程序标题 std::cout << "\n" << std::string(70, '*') << std::endl; std::cout << " TCP CONGESTION CONTROL ALGORITHM COMPARISON TOOL" << std::endl; // 2. 运行三种算法的仿真 RunAlgorithmSimulation("Cubic", "ns3::TcpCubic", MakeCallback(&CwndChangeCubic)); RunAlgorithmSimulation("NewReno", "ns3::TcpNewReno", MakeCallback(&CwndChangeNewReno)); RunAlgorithmSimulation("Vegas", "ns3::TcpVegas", MakeCallback(&CwndChangeVegas)); // 3. 打印对比结果 PrintComparisonTable(); PrintPerformanceRankings(); // 4. 最终总结和建议 // ... return 0; } // Cubic仿真 RunAlgorithmSimulation("Cubic", // 算法名称 "ns3::TcpCubic", // TCP类型 MakeCallback(&CwndChangeCubic)); // 回调函数 // MakeCallback的作用: // 将普通函数指针包装成ns3的Callback对象 // 格式:MakeCallback(返回类型, 参数类型...)

八、关键技术和设计模式

// 1. 定义回调函数 static void MyCallback(uint32_t param1, uint32_t param2); // 2. 创建Callback对象 Callback<void, uint32_t, uint32_t> cb = MakeCallback(&MyCallback); // 3. 连接信号和回调 socket->TraceConnectWithoutContext("SignalName", cb); // 4. 当信号触发时,自动调用MyCallback // Helper类示例 PointToPointHelper pointToPoint; InternetStackHelper stack; Ipv4AddressHelper address; // 作用:简化复杂对象的创建和配置 // 提供一致的接口 // 隐藏实现细节 NodeContainer nodes; // 节点容器 NetDeviceContainer devices; // 网络设备容器 ApplicationContainer apps; // 应用容器 // 作用:统一管理相关对象 // 方便批量操作 // 提供迭代器访问

输出结果如下:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/31 1:51:49

普中开发板基于51单片机贪吃蛇游戏设计

基于51单片机贪吃蛇游戏设计( proteus仿真程序设计报告讲解视频&#xff09; 仿真图proteus8.17(有低版本) 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;P24 1主要功能&#xff1a; 基于51单片机的贪吃蛇游戏设计 1、采用8*8点…

作者头像 李华
网站建设 2026/4/1 12:34:00

《从零入门 Ascend C:手把手实现高性能向量加法自定义算子》

1. 引言&#xff1a;为什么需要 Ascend C&#xff1f;在深度学习模型训练与推理中&#xff0c;标准算子库&#xff08;如 cuDNN、ACL&#xff09;虽已高度优化&#xff0c;但面对新型网络结构、特殊数据格式或极致性能需求时&#xff0c;往往力不从心。此时&#xff0c;开发者需…

作者头像 李华
网站建设 2026/4/7 17:59:33

DroidCam零基础入门:5分钟把手机变电脑摄像头

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 制作一个交互式新手引导应用&#xff0c;通过动画演示和简单步骤&#xff1a;1) 如何在手机和电脑上安装DroidCam&#xff1b;2) 基础连接设置图解&#xff1b;3) 常见应用场景展示…

作者头像 李华
网站建设 2026/3/24 21:43:12

电商大促期间如何预防503错误?7个实战方案

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个电商高可用性监控系统&#xff0c;功能&#xff1a;1. 实时监控服务器负载 2. 预测流量峰值 3. 自动触发扩缩容 4. 优雅降级策略 5. 503错误预警。当检测到可能引发503的情…

作者头像 李华
网站建设 2026/4/6 23:43:28

Prompt工程能否代替模型训练?

Prompt 工程很强&#xff0c;但替代不了「模型训练」本身。下面我们从底层视角拆开看看&#xff1a;Transformer 在干嘛&#xff1f;Prompt 在干嘛&#xff1f;训练在干嘛&#xff1f;它们的边界到底在哪里&#xff1f;1 LLM的本质 可以把一个大模型抽象成一个条件概率分布&…

作者头像 李华
网站建设 2026/4/4 14:46:51

用AI优化GPU性能测试:Furmark的智能分析新思路

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个基于AI的GPU性能分析工具&#xff0c;能够自动解析Furmark测试数据。要求&#xff1a;1. 实时读取Furmark测试结果数据 2. 使用机器学习模型分析温度曲线、帧率稳定性等指标…

作者头像 李华