首页 > 其他分享 >ns-3_ Day 8

ns-3_ Day 8

时间:2023-01-10 09:55:06浏览次数:31  
标签:TypeId 聚合 trace 对象 Object ns Day 属性

对象模型

ns-3对象模型通过3个基类Object、ObjectBase、SimpleRefCount定义了ns-3中绝大部分C++类的行为和关系。

  • SimpleRefCount解决针对单个类的动态内存管理问题。这在前面的Ptr已经讲了。
  • ObjectBase解决配置属性和trace变量的问题。它定义了对这些变量进行配置的方法和存储数据结构。
  • Object解决多个类的动态关联问题,解决的方法是对象聚合(Object Aggregation)。可以让一个Object对象在运行时关联其他对象。

Object:理解对象聚合

对象聚合就是对象关联,这些对象都是Object的派生类。
看一段Object的代码:

class Object : public SimpleRefCount<Object, ObjectBase, ObjectDeleter>
{
public:
	//添加聚合对象
    void AggregateObject(Ptr<Object> other);
	//依据类名查找对应对象
    template <typename T>
    inline Ptr<T> GetObject(void) const;

private:
	//聚合数组
    struct Aggregates
    {
        uint32_t n;						//聚合数组元素数量
        Object *buffer[1];				//聚合数组起始指针
    };
    struct Aggregates *m_aggregates;	//聚合数组
}

一个Object的派生类持有一个聚合数组m_aggregates,包含其所有的关联对象。这些关联对象彼此地位平等,持有的聚合数组也是完全一样的。

创建Object

  1. 创建ObjectFactory对象 ObjectFactory pppF;
  2. 设置对象属性 pppF.SetTypeId(); pppF.Set();
  3. pppF.Create<>();

GetObject

查找关联对象,用法如下:

Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
Ptr<Ipv4L3Protocol> ipv4 = node->GetObject<Ipv4L3Protocol>();

上面两行是等价的,只是查找到的指针类型不同(Ipv4是Ipv4L3Protocol的基类)。因此GetObject的另一个用法是指针上下行转换:

Ptr<Ipv4L3Protocol> ipv4L3Prot = ipv4->GetObject<Ipv4L3Protocol>();

查找失败则返回空指针。

元信息

GetObject的技术原理是元信息(meta information)。元信息是关于ObjectBase及其派生类的辅助信息,每一个派生类具有唯一的一组元信息。
image.png
所有元信息被存储在一个vector中,类名作为查找关键字,实体类是IidManager。
ObjectBase的派生类会保存其元信息的索引值,保存在TypeId之中。可以把元信息的结构理解成:
image.png
查找的实现思路:

  1. 获取模板中类的TypeId tid;
  2. 把tid和聚合数组中的每个元素的TypeId进行比较;
  3. 把tid和聚合数组中的每个元素的基类TypeId进行比较;

举例:GetObject()在聚合数组[ipv6L3Protocol, ipv4L3Protocol]的搜索路径
image.png

ObjectBase:实现配置功能

前面已经看到,属性和trace信息保存在元信息之中。实际上属性系统和trace系统就是元信息以及对应的函数。

属性

属性值类型不可以互转,但都可以转换成StringValue。
image.png

  • ConfigStore可以用于保存脚本中用过的属性集为一个文件,并在下一次模拟中加载。
  • 全局属性不属于任何一个类,都是一些影响模拟器行为或者性能的变量。ns-3支持的全局属性有限。

举例:PointToPointNetDevice的传输速率属性

class PointToPointNetDevice : public NetDevice
{
private:
    DataRate m_bps;
};
TypeId PointToPointDevice::GetTypeId(void)
{
    static TypeId tid = TypeId("ns3::PointToPointNetDevice")
		.AddAttribute(
			"DataRate", 	//属性名
			DataRateValue(DataRate("32768b/s")), //默认值
			MakeDataRateAccessor(&PointToPointNetDevice::m_bps));//创建了一个属性访问函数并将函数指针存放在属性辅助信息中
    return tid;
}

trace

trace变量本质上是一个函数指针的成员变量,trace系统的作用就是把函数指针变成一个可以配置的变量。
举例:一个PointToPointDevice的分组接收trace

class PointToPointNetDevice : public NetDevice
{
private:
    TracedCallback<Ptr<const Packet>> m_macRxTrace;
};
TypeId PointToPointDevice::GetTypeId(void)
{
    static TypeId tid = TypeId("ns3::PointToPointNetDevice")
		.AddTraceSource(
			"MacRx", 	//trace名
			MakeTraceSourceAccessor(&PointToPointNetDevice::m_macRxTrace), //创建了一个trace访问函数并将其函数指针存放在trace辅助信息中
			"ns3::Packet::TracedCallback");	//指定回调函数的签名是Packet类的TracedCallback函数指针
    return tid;
}

void PointToPointNetDevice::Receive(Ptr<Packet> packet)
{
	m_macRxTrace(originalPacket);	//使用回调的方法
}

当m_macRxTrace作为一个TracedCallback被声明后,它就成为了一个可以在脚本中配置的trace变量。
和属性辅助信息一样,trace变量的辅助信息也在初始化TypeId的时候指定。
ns-3的trace变量的签名格式主要有两种:

  • TracedCallback类型 主要用于和分组相关的行为事件(如分组收发、丢失)
    • 返回值为void(因为这些trace变量只用作提供数据,不需要返回),形参最多8个
    • 签名格式命名习惯为 ns3::类名或命名空间::typedef名,举例:
      • Ipv4L3Protocol类的分组发送trace变量Tx的签名格式:ns3::Ipv4L3Protocol::TxRxTracedCallback
      • 使用最广泛的签名格式是 ns3::Packet::TracedCallback
    • trace变量对应的函数指针都是TracedCallback类的对象
  • TracedValue类型 主要用于一个数值变量的大小变化事件(如TCP拥塞窗口大小变化、一个队列中分组数目变化)
    • 其内部就是只有两个形参的TracedValueCallback对象
    • 只需要记录旧数值和新数值两个变量即可

标签:TypeId,聚合,trace,对象,Object,ns,Day,属性
From: https://www.cnblogs.com/leewaytang/p/17039241.html

相关文章