ns3学习(1):TypeId、TraceSource

一、什么是TypeId

TypeId 实际上它就是一个资源管理器,我们把每一个类都赋予其对应的 TypeId,那么我们可以通过类名找到对应的 TypeId,使得我们代码可以是一个弱关联关系,不一定要在编译阶段就 include 这个类,可以在运行时再通过连接的方式找到对应类!
所以我们用 gcc 是很难编译一个 ns3 代码的,它就不是传统的那种写法,一定需要 waf 来编译。

如果设计模式学的比较好应该可以理解,这个其实是一个策略模式。
我们通过弱解耦的方式把不同的方法引进来,例如我们要把拥塞控制算法从 Reno 换成 BBR,只需要写一个 BBR 的类,然后 Set 进去就好了,而不需要改其他代码(甚至 #include 部分都不用改)。

二、如何注册TypeId

下面是一段官方文档内的代码,关于官方给的TypeId注册与使用示例

class MyObject : public Object
{
public:
static TypeId GetTypeId (void)
{
static TypeId tid = TypeId ("MyObject")
.SetParent (Object::GetTypeId ())
.AddConstructor<MyObject> ()
.AddTraceSource ("MyInteger",
"An integer value to trace.",
MakeTraceSourceAccessor (&MyObject::m_myInt))
;
return tid;
}

MyObject () {}
TracedValue<uint32_t> m_myInt;

};


void
IntTrace (Int oldValue, Int newValue)
{
std::cout << "Traced " << oldValue << " to " << newValue << std::endl;
}


int
main (int argc, char *argv[])
{
Ptr<MyObject> myObject = CreateObject<MyObject> ();
myObject->TraceConnectWithoutContext ("MyInteger", MakeCallback(&IntTrace));
myObject->m_myInt = 1234;
}

在类MyObject的定义中,可以看到注册Type的流程:

class MyObject : public Object
{
public:
static TypeId GetTypeId (void)
{
static TypeId tid = TypeId ("MyObject")
.SetParent (Object::GetTypeId ())
.AddConstructor<MyObject> ()
.AddTraceSource ("MyInteger","An integer value to trace.",MakeTraceSourceAccessor (&MyObject::m_myInt));
return tid;
}

MyObject () {}
TracedValue<uint32_t> m_myInt;

};

我们可以如下图所示地查找构造函数TypeId()、成员函数SetParent()、AddConstructor()、AddTraceSource()的含义。为了更简单可以在网页中 ctrl+F 查找需要的内容

在这里插入图片描述

1、点进绿色字体的链接可以看到,下面这行代码所示的“MyObject”就是接口的名字,而且必须是独一无二,不可以相同的。

static TypeId tid = TypeId ("MyObject")

在这里插入图片描述

2、如下图:setParent括号内的是此类的基类。

.SetParent (Object::GetTypeId ())

在这里插入图片描述
3、如下图:AddConstructor,记录默认构造函数可访问。

.AddConstructor<MyObject> ()

在这里插入图片描述

4、AddTraceSource是为了添加TraceSource,同样可以在TypeId的类中找到这个方法,他的描述是Record a new TraceSource。其参数的含义如下图。

.AddTraceSource ("MyInteger","An integer value to trace.",MakeTraceSourceAccessor (&MyObject::m_myInt));

traceSource我的理解是指一个事件。
所以这段代码的含义可以理解是 记录了一个叫做“MyInteger”的事件,这个事件的描述是"An integer value to trace.",这个事件具体是指m_mInt的值发生变化。

  • 更多traceSource的理解可以看这个文档

在这里插入图片描述

5、常用的组还有setGropName(),指此类所在的组,例如Cubic的组是Tcp。
在这里插入图片描述

AddAttribute用于在此TypeId中记录 新属性。

  • [in]name新属性的名称
  • [in]help一些描述此属性用途的帮助文本
  • [in]flags描述如何读取和/或写入此属性的标志。
  • [in]initialValue此属性的初始值。
  • [in]accessor关联AttributeAccessor子类的实例
  • [in]checker关联的AttributeChecker子类的实例。
  • [in]supportLevel属性的支持/弃用状态。
  • [in]supportMsg升级提示(如果不再支持此属性)。如果属性已弃用,则属性行为仍然存在,但应按照提示中的指导更新用户代码。。如果属性是OBSOLETE,则提示应指示属性函数已移动到哪个类,或者不再支持该功能。

例如:

    .AddAttribute ("MaxSize",//添加属性:最大尺寸
                   "The max queue size",//注释,最大队列长度
                   QueueSizeValue (QueueSize ("1000p")),
                   MakeQueueSizeAccessor (&QueueDisc::SetMaxSize,
                                          &QueueDisc::GetMaxSize),
                   MakeQueueSizeChecker ())   

在这里插入图片描述

三、如何使用TypeId

在如上文中的示例中,我们就注册了一个名字叫“MyObject”的TypeId。类似的我们可以注册其他不同名字的TypeId。

首先查找看是否有这样的类:
[in] name The name of the requested TypeId
[out] tid A pointer to the TypeId instance where the result of this function should be stored.

transport_prot0 = std::string("ns3::TcpCubic") ;
TypeId tcpTid;
bool ok = TypeId::LookupByNameFailSafe (transport_prot0, &tcpTid);
if (!ok) {
std::cout << "TypeId " << transport_prot0 << " not found" << std::endl;
exit(1);
}

通过一个TypeId name找到一个TypeId对象,返回给&tcpTid这个引用。

下一步就是经过上面的查找后,将这个协议栈更改,添加到SocketType属性中。
例如:假如transport_port0是TcpCubic,那就设置左右节点的协议栈为TcpCubic

Ptr<TcpL4Protocol> protol;
Ptr<TcpL4Protocol> protor;
for (uint32_t i = 0; i < num_leaf; ++i) {
protol = leftleaf.Get(i)->GetObject<TcpL4Protocol> ();
protor = rightleaf.Get(i)->GetObject<TcpL4Protocol> ();
if (i < num_cca0) {
protol->SetAttribute ("SocketType", TypeIdValue
(TypeId::LookupByName(transport_prot0)));
protor->SetAttribute ("SocketType", TypeIdValue
(TypeId::LookupByName(transport_prot0)));
}
  • 30
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值