You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NS3新手求助:如何编写代码绘制吞吐量/丢包率随时间变化曲线

刚接触NS3就要搞定作业里的吞吐量和丢包率曲线,确实有点摸不着头脑对吧?别担心,咱们从修改你已经在跑的fifth.cc入手,一步步搞定数据收集和绘图!

实现TCP吞吐量&丢包率随时间变化曲线的完整步骤

一、NS3端的数据收集(基于fifth.cc修改)

咱们直接在现有代码上添加数据追踪逻辑,不用从零写新脚本。

1. 收集吞吐量数据(Sink端统计)

吞吐量的核心是每隔固定时间统计Sink接收到的总字节数,再转换成Mbps单位(公式:(字节数*8)/(1024*1024*时间间隔))。

步骤代码:

  • 先在文件开头添加全局变量和文件操作头文件:
#include <fstream>
#include <iostream>
using namespace std;

// 吞吐量统计相关变量
ofstream throughputFile;
double lastStatTime = 0.0;
uint64_t lastRxBytes = 0;
  • 添加追踪Sink接收数据的回调函数:
void RecordThroughput(Ptr<const Packet> packet, const Address& from) {
    double currentTime = Simulator::Now().GetSeconds();
    uint64_t currentRxBytes = packet->GetSize();

    // 每隔1秒统计一次吞吐量(可根据需求调整间隔)
    if (currentTime - lastStatTime >= 1.0) {
        double throughputMbps = (currentRxBytes - lastRxBytes) * 8.0 / (1024 * 1024 * (currentTime - lastStatTime));
        throughputFile << currentTime << " " << throughputMbps << endl;

        // 更新统计基准
        lastStatTime = currentTime;
        lastRxBytes = currentRxBytes;
    }
}
  • 在创建TCP Sink的代码段,绑定这个回调:
// 找到原代码中创建sink的部分,添加绑定逻辑
Ptr<PacketSink> sink = CreateObject<PacketSink>();
sink->SetAttribute("Protocol", TypeIdValue(TcpSocketFactory::GetTypeId()));
nodes.Add(sink);
sink->SetNode(nodes.Get(1));
// 绑定接收数据的追踪回调
sink->TraceConnectWithoutContext("Rx", MakeCallback(&RecordThroughput));
  • 在Simulator::Run()前打开输出文件,运行结束后关闭:
// 打开吞吐量数据文件
throughputFile.open("throughput_data.txt");
throughputFile << "Time(s) Throughput(Mbps)" << endl; // 可选表头

Simulator::Run();

// 关闭文件
throughputFile.close();
Simulator::Destroy();

2. 收集丢包数据(配合你的MATLAB处理)

如果你已经有丢包事件数据,这部分可以按需补充;如果需要更精准的丢包统计,咱们可以在NS3里追踪链路丢包:

  • 添加丢包统计的全局变量和文件:
ofstream lossFile;
uint64_t totalLost = 0;
double lastLossStatTime = 0.0;
  • 添加丢包追踪的回调函数:
void RecordPacketLoss(Ptr<const Packet> packet, const Address& from) {
    double currentTime = Simulator::Now().GetSeconds();
    totalLost++;

    // 每隔1秒统计累计丢包数(也可以直接记录每个丢包的时间点)
    if (currentTime - lastLossStatTime >= 1.0) {
        lossFile << currentTime << " " << totalLost << endl;
        lastLossStatTime = currentTime;
    }
    // 若需记录单个丢包时间,直接写:lossFile << currentTime << " 1" << endl;
}
  • 绑定到点对点链路的接收端设备:
// 找到原代码中创建点对点设备的部分
NetDeviceContainer devices = pointToPoint.Install(nodes);
// 绑定丢包追踪到接收端设备
devices.Get(1)->TraceConnectWithoutContext("Drop", MakeCallback(&RecordPacketLoss));
  • 同样在Run前打开文件,结束后关闭:
lossFile.open("loss_data.txt");
lossFile << "Time(s) TotalLostPackets" << endl;

Simulator::Run();

lossFile.close();
Simulator::Destroy();

二、用MATLAB绘制曲线

现在你已经拿到throughput_data.txt和丢包相关数据,直接用MATLAB处理绘图即可。

1. 绘制吞吐量曲线

% 加载吞吐量数据
data = load('throughput_data.txt');
time = data(:, 1);
throughput = data(:, 2);

figure;
plot(time, throughput, 'b-', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('吞吐量 (Mbps)');
title('TCP吞吐量随时间变化曲线');
grid on;
set(gca, 'FontSize', 10);

2. 绘制丢包率曲线

假设你已经有丢包事件时间或每秒丢包数,结合发送数据包数计算丢包率(丢包率=(每秒丢包数/每秒发送数)*100%):

% 加载丢包事件数据(每行一个丢包时间)
loss_events = load('loss_events.txt');
% 加载发送数据统计(每行是时间+每秒发送包数)
send_stats = load('send_data.txt');

% 统计每秒丢包数
time_edges = 0:1:max(send_stats(:,1));
[loss_counts, ~] = histcounts(loss_events, time_edges);
loss_per_sec = loss_counts(1:end-1);
time_axis = 0.5:1:max(send_stats(:,1))-0.5; % 取每秒中间时间点

% 计算丢包率
loss_rate = (loss_per_sec ./ send_stats(:,2)) * 100;

figure;
plot(time_axis, loss_rate, 'r-', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('丢包率 (%)');
title('TCP丢包率随时间变化曲线');
grid on;
set(gca, 'FontSize', 10);

三、小提示

  • 统计间隔可以灵活调整:比如把1秒改成0.5秒,只需要修改回调里的时间判断条件即可。
  • 若拓扑不是点对点,丢包可能发生在其他位置(比如无线节点),需要调整绑定追踪的对象(比如无线NetDevice的Drop事件)。
  • 单位转换别搞错:字节转比特要乘8,转Mbps要除以1024*1024(因为1Mbps=1024*1024 bps)。

内容的提问来源于stack exchange,提问作者Mavimo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:39:05