通过ndnSIM平台内建输出程序 trace helpers 获取的数据只需稍加处理即可得到节点吞吐量、丢包率、时延和缓存命中率等指标,具体过程可以参考:ndnSIM 仿真数据获取 仿真结果 平台内建输出程序 trace helpers 的使用_ndnsim tracer-CSDN博客
如该教程所说,两种方式都能获取仿真数据:
- 打印输出运行日志,并在其中配置需要查看的数据,具体方式可以查看教程:ndnSIM 如何打印 运行日志 获取日志 调试 获取实验数据_ndnsim运行日志-CSDN博客
- 通过平台内建输出程序获取,即使用 trace helpers 来对仿真结果进行跟踪,生成数据文件txt
下面分别介绍这两种获取的数据如何生成实验结果图,可以放在论文中:
Trace helpers 平台内建输出程序
该方法得到的数据均为txt文件,其中的格式和字段含义可以参考教程(ndnSIM 仿真数据获取 仿真结果 平台内建输出程序 trace helpers 的使用_ndnsim tracer-CSDN博客)中的表格内容。
因此,对该txt进行处理即可得到实验结果图。
1.吞吐量(Example of packet-level trace helpers)
此示例(ndn-tree-tracers.cpp)演示了数据包级跟踪助手的基本用法。
在这种情况下,我们将使用树状拓扑,其中使用者安装在叶节点上,而生产者位于树的根目录中:
拓扑结构如下图:
相应的拓扑文件(topo-tree.txt):
# topo-tree.txt
router
#node city y x mpi-partition
leaf-1 NA 80 40 1
leaf-2 NA 80 20 3
leaf-3 NA 80 0 2
leaf-4 NA 80 -20 4
rtr-1 NA 60 20 1
rtr-2 NA 60 0 2
root NA 40 10 0
link
# from to capacity metric delay queue
leaf-1 rtr-1 10Mbps 1 1ms 100
leaf-2 rtr-1 10Mbps 1 1ms 100
leaf-3 rtr-2 10Mbps 1 1ms 100
leaf-4 rtr-2 10Mbps 1 1ms 100
rtr-1 root 10Mbps 1 1ms 100
rtr-2 root 10Mbps 1 1ms 100
使用跟踪助手的示例模拟(ndn-tree-tracers.cpp)场景:
// ndn-tree-tracers.cpp
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/ndnSIM-module.h"
namespace ns3 {
int
main(int argc, char* argv[])
{
CommandLine cmd;
cmd.Parse(argc, argv);
AnnotatedTopologyReader topologyReader("", 1);
topologyReader.SetFileName("src/ndnSIM/examples/topologies/topo-tree.txt");
topologyReader.Read();
// Install NDN stack on all nodes
ndn::StackHelper ndnHelper;
ndnHelper.InstallAll();
// Choosing forwarding strategy
ndn::StrategyChoiceHelper::InstallAll("/prefix", "/localhost/nfd/strategy/best-route");
// Installing global routing interface on all nodes
ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
ndnGlobalRoutingHelper.InstallAll();
// Getting containers for the consumer/producer
Ptr<Node> consumers[4] = {Names::Find<Node>("leaf-1"), Names::Find<Node>("leaf-2"),
Names::Find<Node>("leaf-3"), Names::Find<Node>("leaf-4")};
Ptr<Node> producer = Names::Find<Node>("root");
for (int i = 0; i < 4; i++) {
ndn::AppHelper consumerHelper("ns3::ndn::ConsumerCbr");
consumerHelper.SetAttribute("Frequency", StringValue("100")); // 100 interests a second
// Each consumer will express unique interests /root/<leaf-name>/<seq-no>
consumerHelper.SetPrefix("/root/" + Names::FindName(consumers[i]));
consumerHelper.Install(consumers[i]);
}
ndn::AppHelper producerHelper("ns3::ndn::Producer");
producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
// Register /root prefix with global routing controller and
// install producer that will satisfy Interests in /root namespace
ndnGlobalRoutingHelper.AddOrigins("/root", producer);
producerHelper.SetPrefix("/root");
producerHelper.Install(producer);
// Calculate and install FIBs
ndn::GlobalRoutingHelper::CalculateRoutes();
Simulator::Stop(Seconds(20.0));
ndn::L3RateTracer::InstallAll("rate-trace.txt", Seconds(0.5));
Simulator::Run();
Simulator::Destroy();
return 0;
}
} // namespace ns3
int
main(int argc, char* argv[])
{
return ns3::main(argc, argv);
}
成功运行将直接在当前文件中创建rate-trace.txt文件,可以手动对其进行分析或将其用作某些图形/统计信息包的输入。
# Copyright (c) 2012,2015 Alexander Afanasyev <alexander.afanasyev@ucla.edu>
# install.packages('ggplot2')
library(ggplot2)
# install.packages('scales')
library(scales)
# install.packages('doBy')
library(doBy)
#########################
# Rate trace processing #
#########################
data = read.table("rate-trace.txt", header=T)
data$Node = factor(data$Node)
data$FaceId <- factor(data$FaceId)
data$Kilobits <- data$Kilobytes * 8
data$Type = factor(data$Type)
# exlude irrelevant types
data = subset(data, Type %in% c("InInterests", "OutInterests", "InData", "OutData"))
# combine stats from all faces
data.combined = summaryBy(. ~ Time + Node + Type, data=data, FUN=sum)
data.root = subset (data.combined, Node == "root")
data.leaves = subset(data.combined, Node %in% c("leaf-1", "leaf-2", "leaf-3", "leaf-4"))
# graph rates on all nodes in Kilobits
g.all <- ggplot(data.combined) +
geom_point(aes (x=Time, y=Kilobits.sum, color=Type), size=1) +
ylab("Rate [Kbits/s]") +
facet_wrap(~ Node)
print(g.all)
# graph rates on the root nodes in Packets
g.root <- ggplot(data.root) +
geom_point(aes (x=Time, y=Kilobits.sum, color=Type), size=2) +
geom_line(aes (x=Time, y=Kilobits.sum, color=Type), size=0.5) +
ylab("Rate [Kbits/s]")
print(g.root)
png("src/ndnSIM/docs/source/_static/root-rates.png", width=500, height=250)
print(g.root)
retval <- dev.off()
使用以下语句运行以上R语言脚本,即可得到实验结果图。
Rscript src/ndnSIM/examples/graphs/rate-graph.R
前提:
- 需要在电脑中安装R语言编译运行环境
- 需要安装ggplot2插件
可以参考 R language manual 和 ggplot2 module manual 进行安装。
最终结果:
获取吞吐量的步骤:
- 在代码中加入 ndn::L3RateTracer::InstallAll("rate-trace.txt", Seconds(1.0)); 根据ndnSIM 仿真数据获取 仿真结果 平台内建输出程序 trace helpers 的使用_ndnsim tracer-CSDN博客教程所述;
- 运行以上的R语言代码。
2.丢包率 Example of packet drop tracer (L2Tracer)
此示例(ndn-tree-with-l2tracer.cpp)演示了数据包级跟踪助手的基本用法。
相应的拓扑文件(topo-tree-25-node.txt):
router
# node comment yPos xPos
Rtr1 NA 3 9
Rtr2 NA 9 9
Rtr3 NA 15 9
Rtr7 NA 9 15
Rtr4 NA 3 21
Rtr5 NA 9 21
Rtr6 NA 15 21
Src1 NA 1 3
Src2 NA 3 3
Src3 NA 5 3
Src4 NA 7 3
Src5 NA 9 3
Src6 NA 11 3
Src7 NA 13 3
Src8 NA 15 3
Src9 NA 17 3
Dst1 NA 1 27
Dst2 NA 3 27
Dst3 NA 5 27
Dst4 NA 7 27
Dst5 NA 9 27
Dst6 NA 11 27
Dst7 NA 13 27
Dst8 NA 15 27
Dst9 NA 17 27
link
# srcNode dstNode bandwidth metric delay queue
Src1 Rtr1 100Mbps 1 10ms 10
Src2 Rtr1 100Mbps 1 10ms 10
Src3 Rtr1 100Mbps 1 10ms 10
Src4 Rtr2 100Mbps 1 10ms 10
Src5 Rtr2 100Mbps 1 10ms 10
Src6 Rtr2 100Mbps 1 10ms 10
Src7 Rtr3 100Mbps 1 10ms 10
Src8 Rtr3 100Mbps 1 10ms 10
Src9 Rtr3 100Mbps 1 10ms 10
Rtr1 Rtr7 10Mbps 1 10ms 10
Rtr2 Rtr7 10Mbps 1 10ms 10
Rtr3 Rtr7 10Mbps 1 10ms 10
Rtr4 Rtr7 10Mbps 1 10ms 10
Rtr5 Rtr7 10Mbps 1 10ms 10
Rtr6 Rtr7 10Mbps 1 10ms 10
Dst1 Rtr4 100Mbps 1 10ms 10
Dst2 Rtr4 100Mbps 1 10ms 10
Dst3 Rtr4 100Mbps 1 10ms 10
Dst4 Rtr5 100Mbps 1 10ms 10
Dst5 Rtr5 100Mbps 1 10ms 10
Dst6 Rtr5 100Mbps 1 10ms 10
Dst7 Rtr6 100Mbps 1 10ms 10
Dst8 Rtr6 100Mbps 1 10ms 10
Dst9 Rtr6 100Mbps 1 10ms 10
使用跟踪助手的示例模拟(ndn-tree-with-l2tracer.cpp)场景:
// ndn-simple-withl2tracer.cpp
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/ndnSIM-module.h"
namespace ns3 {
int
main(int argc, char* argv[])
{
CommandLine cmd;
cmd.Parse(argc, argv);
AnnotatedTopologyReader topologyReader("", 10);
topologyReader.SetFileName("src/ndnSIM/examples/topologies/topo-tree-25-node.txt");
topologyReader.Read();
/****************************************************************************/
// Install NDN stack on all nodes
ndn::StackHelper ndnHelper;
ndnHelper.SetOldContentStore("ns3::ndn::cs::Lru", "MaxSize", "1000");
ndnHelper.InstallAll();
/****************************************************************************/
// Installing global routing interface on all nodes
ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
ndnGlobalRoutingHelper.InstallAll();
/****************************************************************************/
// Getting containers for the consumer/producer
Ptr<Node> consumer1 = Names::Find<Node>("Src1");
Ptr<Node> consumer2 = Names::Find<Node>("Src2");
Ptr<Node> consumer3 = Names::Find<Node>("Src3");
Ptr<Node> consumer4 = Names::Find<Node>("Src4");
Ptr<Node> consumer5 = Names::Find<Node>("Src5");
Ptr<Node> consumer6 = Names::Find<Node>("Src6");
Ptr<Node> consumer7 = Names::Find<Node>("Src7");
Ptr<Node> consumer8 = Names::Find<Node>("Src8");
Ptr<Node> consumer9 = Names::Find<Node>("Src9");
Ptr<Node> producer1 = Names::Find<Node>("Dst1");
Ptr<Node> producer2 = Names::Find<Node>("Dst2");
Ptr<Node> producer3 = Names::Find<Node>("Dst3");
Ptr<Node> producer4 = Names::Find<Node>("Dst4");
Ptr<Node> producer5 = Names::Find<Node>("Dst5");
Ptr<Node> producer6 = Names::Find<Node>("Dst6");
Ptr<Node> producer7 = Names::Find<Node>("Dst7");
Ptr<Node> producer8 = Names::Find<Node>("Dst8");
Ptr<Node> producer9 = Names::Find<Node>("Dst9");
/****************************************************************************/
ndn::AppHelper consumerHelper("ns3::ndn::ConsumerCbr");
consumerHelper.SetAttribute("Frequency", StringValue("1000")); // interests per Second
consumerHelper.SetAttribute("Randomize", StringValue("uniform"));
/****************************************************************************/
// on the first to ninth consumer node install a Consumer application
// that will express interests in /dst1 to /dst9 namespace
consumerHelper.SetPrefix("/dst9");
consumerHelper.Install(consumer1);
consumerHelper.SetPrefix("/dst8");
consumerHelper.Install(consumer2);
consumerHelper.SetPrefix("/dst7");
consumerHelper.Install(consumer3);
consumerHelper.SetPrefix("/dst6");
consumerHelper.Install(consumer4);
consumerHelper.SetPrefix("/dst5");
consumerHelper.Install(consumer5);
consumerHelper.SetPrefix("/dst4");
consumerHelper.Install(consumer6);
consumerHelper.SetPrefix("/dst3");
consumerHelper.Install(consumer7);
consumerHelper.SetPrefix("/dst2");
consumerHelper.Install(consumer8);
consumerHelper.SetPrefix("/dst1");
consumerHelper.Install(consumer9);
/****************************************************************************/
ndn::AppHelper producerHelper("ns3::ndn::Producer");
producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
/****************************************************************************/
// Register /dst1 to /dst9 prefix with global routing controller and
// install producer that will satisfy Interests in /dst1 to /dst9 namespace
ndnGlobalRoutingHelper.AddOrigins("/dst1", producer1);
producerHelper.SetPrefix("/dst1");
producerHelper.Install(producer1);
ndnGlobalRoutingHelper.AddOrigins("/dst2", producer2);
producerHelper.SetPrefix("/dst2");
producerHelper.Install(producer2);
ndnGlobalRoutingHelper.AddOrigins("/dst3", producer3);
producerHelper.SetPrefix("/dst3");
producerHelper.Install(producer3);
ndnGlobalRoutingHelper.AddOrigins("/dst4", producer4);
producerHelper.SetPrefix("/dst4");
producerHelper.Install(producer4);
ndnGlobalRoutingHelper.AddOrigins("/dst5", producer5);
producerHelper.SetPrefix("/dst5");
producerHelper.Install(producer5);
ndnGlobalRoutingHelper.AddOrigins("/dst6", producer6);
producerHelper.SetPrefix("/dst6");
producerHelper.Install(producer6);
ndnGlobalRoutingHelper.AddOrigins("/dst7", producer7);
producerHelper.SetPrefix("/dst7");
producerHelper.Install(producer7);
ndnGlobalRoutingHelper.AddOrigins("/dst8", producer8);
producerHelper.SetPrefix("/dst8");
producerHelper.Install(producer8);
ndnGlobalRoutingHelper.AddOrigins("/dst9", producer9);
producerHelper.SetPrefix("/dst9");
producerHelper.Install(producer9);
/*****************************************************************************/
// Calculate and install FIBs
ndn::GlobalRoutingHelper::CalculateRoutes();
Simulator::Stop(Seconds(10.0));
/****************************************************************************/
// Tracer:
L2RateTracer::InstallAll("drop-trace.txt", Seconds(0.5));
Simulator::Run();
Simulator::Destroy();
return 0;
}
} // namespace ns3
int
main(int argc, char* argv[])
{
return ns3::main(argc, argv);
}
成功运行将直接在当前文件中创建drop-trace.txt文件,可以手动分析该文件或将其用作某些图形/统计数据包的输入。
例如,以下R脚本将构建许多漂亮的图形:
#!/usr/bin/env Rscript
# Copyright (c) 2012-2015 Alexander Afanasyev <alexander.afanasyev@ucla.edu>
# install.packages ('ggplot2')
library(ggplot2)
## # install.packages ('scales')
## library (scales)
#########################
# Rate trace processing #
#########################
data = read.table("drop-trace.txt", header=T)
data$Node = factor(data$Node)
data$Kilobits <- data$Kilobytes * 8
data$Type = factor(data$Type)
## data.rtr = data[grep("Rtr", data$Node),]
# graph rates on all nodes in Kilobits
g.all <- ggplot(data, aes(x=Time, y=Kilobits, color=Type)) +
geom_point(size=2) +
geom_line() +
ylab("Packet drop rate [Kbits/s]") +
facet_wrap(~ Node) +
theme_bw()
png("src/ndnSIM/docs/source/_static/l2-rate-tracer.png", width=800, height=500)
print(g.all)
x = dev.off()
使用以下语句运行以上R语言脚本,即可得到实验结果图。
Rscript src/ndnSIM/examples/graphs/drop-graph.R
前提:
- 需要在电脑中安装R语言编译运行环境
- 需要安装ggplot2插件
可以参考 R language manual 和 ggplot2 module manual 进行安装。
最终结果:
获取丢包率的步骤:
- 在代码中加入 ns3::L2RateTracer::InstallAll("rate-trace.txt", Seconds(1.0)); 根据ndnSIM 仿真数据获取 仿真结果 平台内建输出程序 trace helpers 的使用_ndnsim tracer-CSDN博客教程所述;
- 运行以上的R语言代码。
3.缓存命中率 (Example of content store trace helper)
此示例(ndn-tree-cs-tracers.cpp)演示了内容存储跟踪器的基本用法。
在这种情况下,我们将使用与前一个示例相同的树状拓扑,其中消费者安装在叶节点上,而生产者位于树的根中。 主要区别在于每个客户端都从相同的名称空间请求数据:/ root / 1,/ root / 2,...。另一个小区别是在这种情况下,我们不是同时启动应用程序,而是间隔10毫秒启动应用程序。
使用跟踪助手的示例模拟(ndn-tree-cs-tracers.cpp)场景:
// ndn-tree-cs-tracers.cpp
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/ndnSIM-module.h"
namespace ns3 {
int
main(int argc, char* argv[])
{
CommandLine cmd;
cmd.Parse(argc, argv);
AnnotatedTopologyReader topologyReader("", 1);
topologyReader.SetFileName("src/ndnSIM/examples/topologies/topo-tree.txt");
topologyReader.Read();
// Install NDN stack on all nodes
ndn::StackHelper ndnHelper;
ndnHelper.SetOldContentStore("ns3::ndn::cs::Lru", "MaxSize",
"100"); // default ContentStore parameters
ndnHelper.InstallAll();
// Choosing forwarding strategy
ndn::StrategyChoiceHelper::InstallAll("/prefix", "/localhost/nfd/strategy/best-route");
// Installing global routing interface on all nodes
ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
ndnGlobalRoutingHelper.InstallAll();
// Getting containers for the consumer/producer
Ptr<Node> consumers[4] = {Names::Find<Node>("leaf-1"), Names::Find<Node>("leaf-2"),
Names::Find<Node>("leaf-3"), Names::Find<Node>("leaf-4")};
Ptr<Node> producer = Names::Find<Node>("root");
for (int i = 0; i < 4; i++) {
ndn::AppHelper consumerHelper("ns3::ndn::ConsumerCbr");
consumerHelper.SetAttribute("Frequency", StringValue("10")); // 100 interests a second
// Each consumer will express the same data /root/<seq-no>
consumerHelper.SetPrefix("/root");
ApplicationContainer app = consumerHelper.Install(consumers[i]);
app.Start(Seconds(0.01 * i));
}
ndn::AppHelper producerHelper("ns3::ndn::Producer");
producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
// Register /root prefix with global routing controller and
// install producer that will satisfy Interests in /root namespace
ndnGlobalRoutingHelper.AddOrigins("/root", producer);
producerHelper.SetPrefix("/root");
producerHelper.Install(producer);
// Calculate and install FIBs
ndn::GlobalRoutingHelper::CalculateRoutes();
Simulator::Stop(Seconds(20.0));
ndn::CsTracer::InstallAll("cs-trace.txt", Seconds(1));
Simulator::Run();
Simulator::Destroy();
return 0;
}
} // namespace ns3
int
main(int argc, char* argv[])
{
return ns3::main(argc, argv);
}
成功运行将创建cs-trace.txt,该文件类似于跟踪示例中的跟踪文件,可以手动进行分析或用作某些图形/统计信息包的输入。
4.时延(Example of application-level trace helper)
此示例(ndn-tree-app-delay-tracer.cpp)演示了应用程序级兴趣数据延迟跟踪器的基本用法。
在这种情况下,我们将使用与数据包跟踪帮助程序示例中相同的树状拓扑,其中消费者安装在叶节点上,生产者位于树的根中,并且客户端从同一名称空间请求数据:/ root / 1,/ root / 2,...
使用跟踪助手的示例模拟(ndn-tree-app-delay-tracer.cpp)场景:
// ndn-tree-app-delay-tracer.cpp
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/ndnSIM-module.h"
namespace ns3 {
int
main(int argc, char* argv[])
{
CommandLine cmd;
cmd.Parse(argc, argv);
AnnotatedTopologyReader topologyReader("", 1);
topologyReader.SetFileName("src/ndnSIM/examples/topologies/topo-tree.txt");
topologyReader.Read();
// Install CCNx stack on all nodes
ndn::StackHelper ndnHelper;
ndnHelper.InstallAll();
// Choosing forwarding strategy
ndn::StrategyChoiceHelper::InstallAll("/prefix", "/localhost/nfd/strategy/best-route");
// Installing global routing interface on all nodes
ndn::GlobalRoutingHelper ndnGlobalRoutingHelper;
ndnGlobalRoutingHelper.InstallAll();
// Getting containers for the consumer/producer
Ptr<Node> consumers[4] = {Names::Find<Node>("leaf-1"), Names::Find<Node>("leaf-2"),
Names::Find<Node>("leaf-3"), Names::Find<Node>("leaf-4")};
Ptr<Node> producer = Names::Find<Node>("root");
ndn::AppHelper consumerHelper("ns3::ndn::ConsumerBatches");
consumerHelper.SetPrefix("/root");
consumerHelper.SetAttribute("Batches", StringValue("1s 1 10s 1"));
consumerHelper.Install(consumers[0]);
consumerHelper.SetAttribute("Batches", StringValue("11s 1"));
consumerHelper.Install(consumers[1]);
consumerHelper.SetAttribute("Batches", StringValue("11s 1"));
consumerHelper.Install(consumers[2]);
ndn::AppHelper producerHelper("ns3::ndn::Producer");
producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
// Register /root prefix with global routing controller and
// install producer that will satisfy Interests in /root namespace
ndnGlobalRoutingHelper.AddOrigins("/root", producer);
producerHelper.SetPrefix("/root");
producerHelper.Install(producer).Start(Seconds(9));
// Calculate and install FIBs
ndn::GlobalRoutingHelper::CalculateRoutes();
Simulator::Stop(Seconds(20.0));
ndn::AppDelayTracer::InstallAll("app-delays-trace.txt");
Simulator::Run();
Simulator::Destroy();
return 0;
}
} // namespace ns3
int
main(int argc, char* argv[])
{
return ns3::main(argc, argv);
}
成功运行将创建app-delays-trace.txt,类似于数据包跟踪帮助程序示例中的跟踪文件,可以手动对其进行分析或将其用作某些图形/统计信息包的输入。
运行日志的数据处理
通过打印运行日志获取的数据同样处理起来较为简单,仅需统计特定NS_LOG出现的次数即可,我们用教程(ndnSIM 如何打印 运行日志 获取日志 调试 获取实验数据_ndnsim运行日志-CSDN博客)中获得的out.log文件为例,展示如何使用Python计算缓存命中率和节点吞吐量。
计算缓存命中率
分别统计forwarder.cpp中onContentStoreHit
和onContentStoreMiss
方法调用次数,即统计out.log中包含字符串"onContentStoreHit"
和"onContentStoreMiss"
的行数:
hits = 0.0
misses = 0.0
f = open(r"out.log")
line = f.readline()
while line:
if "onContentStoreHit" in line:
hits += 1.0
if "onContentStoreMiss" in line:
misses += 1.0
line = f.readline()
f.close()
hit_ratio = hits / (hits + misses)
需要注意的是以上统计的是全网平均命中率,若需统计单个节点的命中率,则只需依据节点号(每一行中第二个元素)分别计算即可。若只统计特定时间段内(如缓存系统稳定时)的命中率,则只需依据日志记录时间(每一行中第一个元素)分段计算即可。
计算节点吞吐量
实验中最常使用的吞吐量数据是服务器负载,即每秒钟发出的数据包个数。所以统计out.log文件中包含字符串"responding with Data"
的行数再除以实验运行时间即可获得服务器负载(同样可以分段统计)。
packets = 0.0
f = open(r"out.log")
line = f.readline()
while line:
if "responding with Data" in line:
packets += 1.0
line = f.readline()
f.close()
server_load = packets / 20.0
若统计单个节点的吞吐量,则依据节点号分别计算forwarder.cpp中onIncomingInterest
、onOutgoingInterest
、onIncomingData
和onOutgoingData
方法调用次数即可,此处若按统计包含同名字符串的行数的方式计算可能会有重复(同一方法内出现两次或多次同名字符串,具体要看源码),因此稳妥起见,最好在这些方法中自定义NS_LOG
信息并统计包含自定义字符串的行数。比如在onOutgoingData
方法添加NFD_LOG_DEBUG("Custom string");
,然后统计out.log文件中包含字符串"Custom string"
的行数。
void Forwarder::onOutgoingData(const Data& data, Face& outFace){
···
NFD_LOG_DEBUG("Custom string");
···
}
packets = 0.0
f = open(r"out.log")
line = f.readline()
while line:
if "Custom string" in line:
packets += 1.0
line = f.readline()
f.close()
计算其他指标
使用打印运行日志的方式计算其他的指标时,若源码中提供相应的NS_LOG
(NFD_LOG_DEBUG
或NS_LOG_INFO
或其他)信息,则统计out.log文件中包含该信息中字符串的行数即可。若不提供或者新增自定义函数,则在需要统计的地方加入NS_LOG(*)
,其中*
需要使用一个独特的字符串记号可与其他文本区别,然后统计out.log文件中包含该字符串记号的行数即可,示例同前述的NFD_LOG_DEBUG("Custom string");
。
NDN科研工作者,长期研究,欢迎讨论交流与合作!