一,平均包时延统计函数
FlowMonitor
是NS-3中的一个模块,用于监视网络流量,并收集关于数据流的各种统计数据。这些统计数据可以用来评估网络协议或应用的性能。FlowMonitor
提供了统一的接口来访问流量相关的度量,如吞吐量、时延、丢包率等。
在执行脚本中可以写入如下平均包时延计算代码,它的原理是遍历FlowMonitor统计的每一条流,其中记录的流中每个包时延信息的总和在it.second.delaySum
中,累加记录到delaySum中,将它除以每条流的接收数据包的数目it.second.rxPackets
的总和packetnum,可以得到总的平均包时延。
void ComputePacketDelay(Ptr<FlowMonitor> fm)
{
// 获取统计结果
FlowMonitor::FlowStatsContainer flowStats = fm->GetFlowStats();
double delaySum = 0.0;
int packetnum = 0;
// 计算每个流的数据包时延
for (auto it : flowStats)
{
if (it.second.txPackets > 0 && it.second.rxPackets > 0)
{
// 计算平均时延
packetnum += it.second.rxPackets;
delaySum += it.second.delaySum.GetSeconds();
}
}
double overallAverageDelay = delaySum / packetnum * 1000;
// 计算总体平均包时延
std::cout << "Overall Average Packet Delay: " << overallAverageDelay << " ms" << std::endl;
}
在main函数中,仿真开始前为所有节点安装FlowMonitor
,在仿真结束后可以执行统计函数输出统计结果。
FlowMonitorHelper fmHelper;//安装流监控器
Ptr<FlowMonitor> fm = fmHelper.InstallAll();
Simulator::Stop (Seconds(1500));
Simulator::Run ();
Simulator::Destroy ();
//统计函数
ComputePacketDelay(fm);
return 0;
二,丢包率统计函数
在执行脚本中可以写入如下丢包率计算代码,它的原理是遍历FlowMonitor统计的每一条流,其中记录的流中发送包的数目在it.second.txPackets
中,减去记录的被接收的包数量it.second.rxPackets
即可得到丢包数目,除以总发包数即为丢包率。
void ComputePacketLossRate(Ptr<FlowMonitor> fm)
{
// 获取统计结果
FlowMonitor::FlowStatsContainer flowStats = fm->GetFlowStats();
uint32_t totalSentPackets = 0;
uint32_t totalReceivedPackets = 0;
// 计算每个流的数据包发送和接收数量
for (auto it : flowStats)
{
if (it.second.txPackets > 0)
{
totalSentPackets += it.second.txPackets;
totalReceivedPackets += it.second.rxPackets;
}
}
// 计算丢包率
uint32_t lostPackets = totalSentPackets - totalReceivedPackets;
double packetLossRate = static_cast<double>(lostPackets) / totalSentPackets * 100.0;
std::cout << "Total Sent Packets: " << totalSentPackets << std::endl;
// std::cout << "Total Received Packets: " << totalReceivedPackets << std::endl;
// std::cout << "Lost Packets: " << lostPackets << std::endl;
std::cout << "Packet Loss Rate: " << packetLossRate << "%" << std::endl;
}
在脚本中的使用方法同包时延计算函数。
FlowMonitorHelper fmHelper;//安装流监控器
Ptr<FlowMonitor> fm = fmHelper.InstallAll();
Simulator::Stop (Seconds(1500));
Simulator::Run ();
Simulator::Destroy ();
//统计函数
ComputePacketLossRate(fm);
return 0;
三,流完成时间统计函数
在执行脚本中可以写入如下流吞吐量计算代码,它的原理是遍历FlowMonitor统计的每一条流,其中记录的流中收到最后一个包it.second.timeLastRxPacket
减去第一个包发送的时间it.second.timeFirstTxPacket
可以得到流完成时间。
void ComputeFlowCompleteTime(FlowMonitorHelper &fmHelper, Ptr<FlowMonitor> fm)
{
// 获取统计结果
FlowMonitor::FlowStatsContainer flowStats = fm->GetFlowStats();
// 计算完成时间
double totalThroughput = 0.0;
double fct = 0;
int validFlows = 0;
for (auto it : flowStats)
{
if (it.second.txBytes > 0)
{
fct += (it.second.timeLastRxPacket - it.second.timeFirstTxPacket).GetSeconds ()*1e3;//单位为毫秒
validFlows++;
}
}
std::cout << "FCT: " << fct/validFlows << " ms" << std::endl;
}
在脚本中的使用方法同包时延计算函数。
FlowMonitorHelper fmHelper;//安装流监控器
Ptr<FlowMonitor> fm = fmHelper.InstallAll();
Simulator::Stop (Seconds(1500));
Simulator::Run ();
Simulator::Destroy ();
//统计函数
ComputeFlowCompleteTime(fmHelper, fm);
return 0;
四,流吞吐量统计函数
在执行脚本中可以写入如下流吞吐量计算代码,它的原理是遍历FlowMonitor统计的每一条流,其中记录的流中收到最后一个包it.second.timeLastRxPacket减去第一个包发送的时间it.second.timeFirstTxPacket可以得到流完成时间,用流的接收数据量it.second.rxBytes(单位是B字节,记得乘以8换算成bytes)除以流完成时间,即可得到流吞吐量。
void ComputeFlowThroughput(FlowMonitorHelper &fmHelper, Ptr<FlowMonitor> fm)
{
// 获取统计结果
FlowMonitor::FlowStatsContainer flowStats = fm->GetFlowStats();
// 计算总吞吐量
double totalThroughput = 0.0;
int validFlows = 0;
for (auto it : flowStats)
{
if (it.second.txBytes > 0)
{
// 确保时间间隔非零
Time duration = it.second.timeLastRxPacket - it.second.timeFirstTxPacket;
if (duration.GetSeconds() > 0)
{
double throughput = it.second.rxBytes * 8.0 / duration.GetSeconds() / 1024 / 1024; // 比特转换为Mbps
totalThroughput += throughput;
//std::cout << "Flow ID: " << it.first << ", Throughput: " << throughput << " Mbps" << std::endl;
}
validFlows++;
}
}
std::cout << "Total Network Throughput: " << totalThroughput << " Mbps" << std::endl;
std::cout << "Avg Network Throughput: " << totalThroughput/validFlows << " Mbps" << std::endl;
}
在脚本中的使用方法同包时延计算函数。
FlowMonitorHelper fmHelper;//安装流监控器
Ptr<FlowMonitor> fm = fmHelper.InstallAll();
Simulator::Stop (Seconds(1500));
Simulator::Run ();
Simulator::Destroy ();
//统计函数
ComputeFlowThroughput(fmHelper, fm);
return 0;
五,网络吞吐量指标
网络吞吐量一般被定义为网络单位时间内接收到的数据量,首先统计接收总数据量,是流接收量it.second.rxBytes
的累加,之后计算最大的it.second.timeLastRxPacket
,为网络收到最后一个包的时间,总接收量除以完成时间即可得到网络吞吐量。
void ComputeNetThroughput(FlowMonitorHelper &fmHelper, Ptr<FlowMonitor> fm)
{
// 获取统计结果
FlowMonitor::FlowStatsContainer flowStats = fm->GetFlowStats();
// 计算总吞吐量
double totalrxbyte = 0.0;
double lastfct = 0;
for (auto it : flowStats)
{
if (it.second.txBytes > 0)
{
// 确保时间间隔非零
Time duration = it.second.timeLastRxPacket - it.second.timeFirstTxPacket;
if (duration.GetSeconds() > 0)
{
double rxbyte = it.second.txBytes * 8.0; // 比特
totalrxbyte += rxbyte;
}
if(it.second.timeLastRxPacket.GetSeconds() > lastfct){
lastfct = it.second.timeLastRxPacket.GetSeconds();
}
}
}
std::cout << "Network Throughput: " << totalrxbyte/lastfct/1024/1024 << "Mbps" << std::endl;
}
在脚本中的使用方法同包时延计算函数。
FlowMonitorHelper fmHelper;//安装流监控器
Ptr<FlowMonitor> fm = fmHelper.InstallAll();
Simulator::Stop (Seconds(1500));
Simulator::Run ();
Simulator::Destroy ();
//统计函数
ComputeNetThroughput(fmHelper, fm);
return 0;