ns-3_ Day 4
脚本编写的有用经验
Helper
每一个模块都有其Helper,源代码位于./src/模块名/helper/
下。例如:
参数输入
attribute是网络模拟中用户可配置的参数,其实就是类的一个变量。例如在P2P网络的例子中,就有如下的设置传输速率的操作:
pointToPoint.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
可以把attribute当成是参数输入。
配置attribute的方法有很多,可以分为如下3类:
Helper
Helper的Set_____Attribute()方法实际上创建的是下一个对象的attribute默认值,因此也仅在对象创建时起作用。
SetAttribute()方法的参数有两个:属性名和属性值。
属性值的表示由类型和值组成。
ObjectBase::SetAttribute
ObjectBase是ns-3中绝大部分表示网络元素类的基类。
一次修改一个属性值,且针对的是已创建对象中的属性(例如要在模拟过程中改变一个网络设备的传输速率)。
基本用法同Helper。
Config::Set()
主要用于设置属性和trace变量。
参数是属性命名空间路径和值。例如:
Config::Set("/NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/DataRate", StringValue("2.5Mbps"));
trace设置
attribute是输入,那么trace就是输出。
对网络模拟中的一些重要网络行为进行记录,并以用户可配置的格式输出结果。
本质上也是成员变量(函数指针)。使用时,在脚本中预先定义一个回调函数,然后通过trace系统将其与某个C++对象内部的函数指针(trace变量)相关联。在模拟过程中,每当有特定的网络行为发生,ns-3就会调用相应的trace变量函数指针,触发回调函数。
通常我们把trace变量的配置放在网络拓扑和应用建立完成之后,因为此时各个网络层的主要C++对象已经建立完毕。但是也有例外,比如Socket对象在应用启动时才被创建,因此一般都用Schedule函数把配置trace变量的操作放在应用程序启动之后。
下面对设置trace的方式进行举例说明:
void MacTxCallback(std::string context, Ptr<const Packet> packet){ NS_LOG_UNCOND("+ " << Simulator::Now().GetSecond() << " " << packet->GetSize() << " " << context); } Config::Connect("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/MacTx", MakeCallback(&MacTxCallback));
上面的代码使用Config::Connect()将函数MacTxCallback赋予所有PointToPointNetDevice对象的trace变量MacTx。每当一个PointToPointNetDevice发送分组时,MacTxCallback函数就会被执行。
MacTxCallback的函数原型怎么确定?重点是参照trace变量的签名,除了第一个参数固定使用std::string context外,其余和trace变量相同即可。
Config::ConnectWithoutContext()函数不需要context参数,其余和Config::Connect()相同。
Helper设置trace实际上是封装了Config::Connect()和Config::ConnectWithoutContext()。
- NetDevice的trace配置:包括PointToPointHelper/CsmaHelper/WifiPhyHelper等。
- InternetStackHelper
命令行
CommandLine cmd; cmd.AddValue("nWifi", "Number of wifi STA devices", nWifi); cmd.Parse(argc, argv);
这样就可以在运行脚本的时候指定nWifi:
./waf --run "third --nWifi=18"
Schedule函数
在模拟过程中,如果需要在特定时间点执行某种操作,就会用到Simulator::Schedule()。
它的参数:
- 相对延迟时间
- 回调函数指针
- 回调函数形参,最多支持6个形参
例如:
static void AdvancePosition(Ptr<Node> node); Simulator::Schedule(Seconds(1.0), &AdvancePosition, ap.Get(0));
如果回调函数是类的成员函数,那么还需要添加一个对象指针参数:
void MyApp::ScheduleTx(void){ m_sendEvent = Simulator::Schedule(tNext, &MyApp::SendPacket, this); }
需要补充的是,ns-3的时间概念是虚拟的。除非使用实时模拟器RealtimeSimulatorImpl,否则在事件调度中,时间只决定调度顺序而不决定调度间隔。
Callback类
为了简化操作,ns-3把回调函数封装在Callback类里。
函数指针由类模板定义,可以定义返回值和最多9个形参。Callback对象的创建和赋值都由MakeCallback()函数来完成。
例如,下面是C++中回调的典型用法:
void MyFunction(int arg){} class MyClass{ void MyMethod(int arg); }; void(*func)(int arg)=0; void(MyClass::*memFunc)(int arg)=0; int main(){ func = MyFunction; //将回调函数MyFunction地址赋给func func(1234); memFunc = &MyClass::MyMethod; MyClass myClass; (myClass.*memFunc)(1234); //等同于myClass.MyMethod(1234) return 0; }
用Callback类将改写成:
Callback<void, int> func; func = MakeCallback(&MyFunction); func(1234); //等同于MyFunction(1234) func = MakeCallback(&MyClass::MyMethod, &myClass); func(1234); //等同于myClass.MyMethod(1234)
除了MakeCallback,ns-3还提供了MakeBoundCallback来创建自带绑定参数的回调函数指针。
例如,下面的MyBoundFunction的信息都将被输出到func.txt中,这是因为stream作为绑定参数被自动添加。
void MyBoundFunction(Ptr<OutputStreamWrapper> stream, int arg){ *stream->GetStream() << arg; } Callback<void, int> funcCallback; AsciiTraceHelper asciiTraceHelper; Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream("func.txt"); funcCallback = MakeBoundCallback(&MyBoundFunction, stream); funcCallback(1234);
这样,即使回调函数多了一个形参,Callback对象的格式仍未改变。
Log系统
trace系统不足以完全了解网络模拟行为和调试程序,因为:
- trace变量无法记录所有的网络事件
- trace变量存储在静态存储区,过多的trace变量不利于大规模模拟
Log系统是轻量级的,用于输出辅助信息。例如:
NS_LOG_INFO("At time " << Simulator::Now().GetSeconds() << "s client sent " << m_size << " bytes to " << Ipv4Address::ConvertFrom(m_peerAddress) << " port " << m_peerPort);
NS_LOG_INFO内部调用的就是std::clog,但是要依附于LOG等级。
LOG可以设置等级或者前缀,用来控制哪些内容被输出。
等级:
前缀:
例如下面的代码,表示打印INFO以上的信息,并且输出该信息所属的节点ID和产生时间。
LogComponentEnable("UdpEchoClientApplication", LogLevel(LOG_LEVEL_INFO|LOG_PREFIX_NODE|LOG_PREFIX_TIME));
posted on 2023-01-07 17:15 LeewayTang 阅读(177) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本