在之前对first.cc例子更改学习trace的时候,用到的回调就是下面的回调,回调trace包含在元信息中。如果想在脚本中用回调的话,就需要在回调所在类GetTypeId()方法中添加回调的信息,如下所示:
NS3中根据回调函数签名格式的不同将回调分成两类
1、TracedCallback签名类型
主要用于与分组相关行为事件(分组收发、丢失等)
这种签名格式的返回值是void,形参最多8个。这些trace只是用来读取传入的参数的,所以返回值设置成void。比如上面的例子用到的就是这类回调。
签名格式的命名通常是"ns3::<类名称或命名空间>::<typedef 名>"
比如"ns3::Packet::TracedCallback",“ns3::Ipv4L3Protocol::TxRxTracedCallback”
2、TracedValue签名类型
主要用于一个数值变量的大小变化的事件(拥塞窗口改变、队列中分组数目改变)
是TracedCallback类型的一个子集,因为跟踪一个变量的变化只需要新旧数值两个参数,用不到8个参数,所以才衍生出TracedValue这个类型。TracedValue类在src/core/model/traced-value.h中定义,内部就是只有两个参数的TracedCallback对象。
例子:
1)、TCP接收窗口的回调:
tcp-socket-base.h文件下的类TcpSocketBase中的trace变量:
TracedValue<uint32_t> m_rWnd; //!< Receiver window (RCV.WND in RFC793)
对应的trace信息:
TypeId
TcpSocketBase::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::TcpSocketBase")
.AddTraceSource ("RWND",
"Remote side's flow control window",
MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd),
"ns3::TracedValueCallback::Uint32")
}
这里的Uint32是src/core/model/traced-value.h中TracedCallback名字空间中定义的函数指针,指向的函数类型返回值void,接收两个32位的参数。
除了这个函数指针之外TracedCallback名字空间下还定义了其他的一些常用函数指针,用途就是接收不同类型的新旧数值。
2)、检测节点位置信息改变:
mobility-model.h文件下的MobilityModel移动模型相关类中有如下回调(为什么这里要用ns3命名空间为前缀呢?)
ns3::TracedCallback<Ptr<const MobilityModel> > m_courseChangeTrace;
TypeId
MobilityModel::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::MobilityModel")
.SetParent<Object> ()
.SetGroupName ("Mobility")
.AddTraceSource ("CourseChange",
"The value of the position and/or velocity vector changed",
MakeTraceSourceAccessor (&MobilityModel::m_courseChangeTrace),
"ns3::MobilityModel::TracedCallback")
;
return tid;
}
具体的移动模型,都是MobilityModel的子类,在位置改变的时候子类会调用父类的这个函数,因此回调绑定的函数被调用
void
MobilityModel::NotifyCourseChange (void) const