NS-3学习笔记 3

今天学学ns-3 Tutorial的第5章Tweaking

5. Tweaking(NS3妙招)

5.1 使用Logging模块

在first.cc脚本中已经见过使用logging的语句了,下面看看logging子系统的具体情况。
1.Logging 概述
大型系统都有日志功能,NS-3也不例外。NS-3认为各种信息级别(例如:error、warning、info、debug…)的日志都是有用的,所以提供了一个可选的、多层级的消息日志系统。日志既可以完全关闭,也可以按模块启动或全局启用。
若要记录debugging info、warnings、error messages,或你想从你的模型中快速得到输出结果,日志系统都是你的首选。目前,有7种级别的日志消息:

  • LOG_ERROR,记录错误,对应宏NS_LOG_ERROR
  • LOG_WARN,记录警告,对应宏NS_LOG_WARN
  • LOG_DEBUG,记录调试信息,对应宏NS_LOG_DEBUG
  • LOG_INFO,记录一般信息,对应宏NS_LOG_INFO
  • LOG_FUNCTION,记录被调用函数的信息。宏NS_LOG_FUNCTION,用于记录成员函数;宏NS_LOG_FUNCTION_NOARGS,用于记录静态函数信息。
  • LOG_LOGIC,记录函数的逻辑过程,对应宏NS_LOG_LOGIC
  • LOG_ALL,记录所有上面提到的信息,无对应宏。
    还有个无条件日志,对应宏为NS_LOG_UNCOND
    下面我们使用上面的一些知识,来获取一些first.cc模拟过程的有趣细节。
    2.启动Logging
    Just to get our bearings,先运行一下原myfirst脚本:

./waf –run scratch/myfirst

这里写图片描述

如果想让UdpEchoClientApplication输出更多信息,那么在命令行下设置环境变量:

export NS_LOG=UdpEchoClientApplication=level_all

再运行脚本可以得到如下结果:
这里写图片描述

从上图中可以看到,UdpEchoClientApplication从创建、配参数、发送、接收,直到最后结束销毁的方法都被显示出来了。这些额外的消息是NS_LOG_FUNCTION级别的,它显示了函数调用的过程。
在有些情况下,可能并不能从上面的日志中知晓消息来源于哪个对象或函数,要弄清到底是谁发出的消息,可以使用或运算符追加prefix_func到NS_LOG环境变量中,例如:

export ‘NS_LOG=UdpEchoClientApplication=level_all|prefix_func’
注意上面的引号”,或号|,中间不能有空格

这里写图片描述

白色高亮显示的部分说明了由send函数发出的1024字节的数据包。其他所有来自于UdpEchoClientApplication的消息都追加了一个函数名前缀,这样就可以知道这个消息到底是谁发出的了。例如,下面可以类似地查看UdpEchoServerApplication:

export ‘NS_LOG=UdpEchoClientApplication=level_all|prefix_func:UdpEchoServerApplication=level_all|prefix_func ’
注意上面的引号‘’、或运算号|、连接号:

这里写图片描述

如果你还想查看log消息产生的时间,那么可以使用或运算符号追加prefix_time,例如:

export ‘NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time:UdpEchoServerApplication=level_all|prefix_func|prefix_time’

这里写图片描述

上面图中高亮显示的部分就是追加prefix_time后的结果。
ps.令我好奇的是,我在自己电脑上做实验,在2.00737s 时UdpEchoClientApplication:HandleRead被调用,官方tutorial中的时间也是2.00737s。莫非模拟过程用时与主机硬件性能无关?这一点反映了什么问题,在分析模拟结果时应注意什么,暂时还不知道,先标记一下。

为了看到模拟过程中所有的隐藏细节,我们可以设置下列系统变量:

export ‘NS_LOG=*=level_all|prefix_func|prefix_time’

之后运行,将输出的大量结果保存到log.out中:

./waf –run scratch/myfirst > log.out 2>&1
注:> log.out 表示把结果输出到log.out 中; 2>&1表示把标准错误输出重定向到标准输出;上面的语句也可以这么写:./waf –run scratch/myfirst &> log.out ,即把标准输出和标准错误输出全都重定向到file中。

当你不知道模拟过程发生了什么错误时,或者想手工排查一下有无问题时,可以考虑使用上面这个设置。

3.在代码中加如Logging
除了设置命令行环境变量NS_LOG外,在代码中也可以追加各个级别的日志。之前在first.cc中有一句:NS_LOG_COMPONENT_DEFINE (“FirstScriptExample”);
例如我们可以在构建节点过程前时,使用NS_LOG_INFO加一些提示消息:

...
NS_LOG_INFO ("Creating Topology");
NodeContainer nodes;
...

下面修改环境变量,然后执行脚本:

export NS_LOG=FirstScriptExample=info
./waf –run scratch/myfirst

这里写图片描述

5.2 使用命令行参数

1. Overriding default attributes
在不改变ns-3脚本的情况下,改变其行为的方法是使用命令行参数。NS-3设计了一套机制来解析这些参数,并把它们作为全局或局部变量完成设置。
在使用命令行参数系统前,要在脚本中声明它。这需要在主函数中写下面的句子:

int
main (int argc, char *argv[])
{
...
CommandLine cmd;
cmd.Parse (argc, argv);
...
}

这两行打开了ns-3全局变量和属性系统。如果不加上的话,后面的操作是不会有预想结果的:
输入命令:

./waf –run “scratch/myfirst –PrintHelp”

会显示有哪些Print命令可用,包括PrintGroups、PrintTypeIds、PrintGroup、PrintAttributes、PrintGlobals
这里写图片描述

现在我们关注一下PrintAttributes,查看一下ns3::PointToPointNetDevice的属性有哪些:

./waf –run “scratch/myfirst –PrintAttributes=ns3::PointToPointNetDevice”

这里写图片描述

这些属性有一部分我们在程序里设置过,而另一些还未设置,其值为默认值。例如:DataRate我们在first.cc中设置为5Mbps,而其默认值为32768bps,如果不在脚本中明确修改该值,那么它将以默认值运行。实验就不做了,思路就是去掉相关脚本语句,然后设置日志环境变量为

export ‘NS_LOG=UdpEchoServerApplication=level_all|prefix_time’

然后运行程序查看日志情况,会发现echoServer接收到数据包时的时间变长了(速率慢了)。这里的重点是要介绍在运行时如何改变属性的默认值,可以使用下面的命令:

./waf –run “scratch/myfirst –ns3::PointToPointNetDevice::DataRate=5Mbps”

这与在代码中修改DataRate的效果一样,但方式不同。下面在看一例,先查看PointToPointChannel的属性,然后修改其部分属性:

./waf –run “scratch/myfirst –PrintAttributes=ns3::PointToPointChannel”
./waf –run “scratch/myfirst –ns3::PointToPointNetDevice::DataRate=5Mbps –ns3::PointToPointChannel::Delay=5ms”

上面的命令在修改DataRate后,又修改了信道延迟Delay的值、MaxPackets的值,两个设置在中间用空格隔开。

./waf –run “scratch/myfirst –ns3::PointToPointNetDevice::DataRate=5Mbps –ns3::PointToPointChannel::Delay=5ms –ns3::UdpEchoClient::MaxPackets=2”

2.hook自己的值
使用AddValue,可以把自己的hook加到命令行中去。下面作为一个例子,我们要使用这个功能设置echo包的发送数量。首先要在first.cc中增加一个局部变量nPckets:

int
main (int argc, char *argv[])
{
uint32_t nPackets = 1;
CommandLine cmd;
cmd.AddValue("nPackets", "Number of packets to echo", nPackets);
cmd.Parse (argc, argv);
...
echoClient.SetAttribute ("MaxPackets", UintegerValue (nPackets));

并使用cmd.AddValue()、cmd.Parse()方法将其加入命令行系统,而且在后面设置MaxPackets属性的地方使用nPackets替换原有的常量1。
现在运行脚本,并使用–PrintHelp打印出可设置命令行参数,你会看到Program Argument(老版本的似乎是User argument)那一列中有nPackets。

./waf –run “scratch/myfirst –PrintHelp”
./waf –run “scratch/myfirst –nPackets=2”

这里写图片描述

从上图中可以看到,echo发了两个来回。

5.3 使用Tracing系统

模拟程序运行后要得到输出结果,这是进行模拟的目标。NS-3的Tracing系统就是用于生成输出结果的主要机制。标准的C++输出有一些问题,所以ns3提供了一套通用时间跟踪子系统来解决输出问题。这个系统的目标有3个:

  • 对于基本的任务,Tracing系统允许用户对一般tracing源生成标准tracing,并且自定义哪个对象生成这些Tracing。
  • Intermediate users中级用户必须能够扩展tracing系统,改变输出格式,或插入新的Tracing源,同时不改变模拟核心模块。
  • 高级用户能够修改模拟核心模块,增加新的Tracing源和sinks。

NS-3的Tracing系统由相互独立的Tracing sources和Tracing sinks组成,以及一个连接source和sinks的标准机制。Tracing sources是在模拟过程中能够发出事件信号并能对相关数据进行访问的实体。例如,跟踪源可能指出何时一个数据包被网络设备接收,而且能对这个包的内容进行访问。
Tracing sources对其本身而言用处不大,他们必须连接到别的代码,即利用源提供的信息完成某些工作sinks上。Tracing sinks是事件和时间的消费者,而Tracing sources是生产者。例如,一个连接到某个source上的sink,可以打印出我们感兴趣的已接受数据包。
Tracing Sources与Tracing sinks之间清晰的划分,有利于用户将新类型的sinks连接到已存在的sources上,而不用编写或重新编译模拟器核心模块。用户可以在自己的代码中定义新的sink,然后连接在核心模块定义的source上。下面我们将浏览一下预定义的Tracing sources和sinks,以及如何自定义。而《ns-3 manual》一书中有详细讲解。

1.ASCII Tracing
ns3提供了一些工具来包装底层Tracing系统,使用户能够配置一些简单的包跟踪。
下面我们试着以ASCII文件来查看输出结果。打开scratch/myfirst.cc中,在Simulator::Run()之前增加下列代码:

AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));

ascii.CreateFileStream ()方法将生成一个对象,用于代表文件myfirst.tr,并将这个对象交给EnableAsciiAll()。EnableAsciiAll()告诉工具你想对point-to-point设备使用ASCII Tracing,打开对该设备的Tracing,并且希望使用trace sinks将有关数据包的信息以ASCII格式输出。下面编译运行一下脚本:

./waf –run scratch/myfirst

运行后,会发现当前目录下出现了myfirst.tr文件,打开以后内容如下:

  • 2 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue ns3::PppHeader (Point-to-Point Protocol: IP (0x0021)) ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 64 id 0 protocol 17 offset (bytes) 0 flags [none] length: 1052 10.1.1.1 > 10.1.1.2) ns3::UdpHeader (length: 1032 49153 > 9) Payload (size=1024)
  • 2 /NodeList/0/DeviceList/0/ ns3::PointToPointNetDevice/TxQueue/Dequ<
  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值