NS3中的一些编程概念

组织结构

NS-3是开源软件,整体的组织结构在src目录中实现
src/core中的是内核模块,内核模块对于现在所有的协议 硬件 以及场景模型都是通用的
src/network中的是网络模块 刻画了分组这个最基本的单元
这两个模块的实现可以为不同的网络仿真提供一般性服务

伪随机数生成器 PRNG

ns-3的随机变量通过调用类ns3::RandomVariableStream 提供 这个类是对底层的随机数生成器进行封装并提供相关接口供用户使用的类
在默认情况下,ns-3使用固定的seed,但是,如果需要仿真的程序需要一定的随机性,不改变seed或运行标识的前提下,仿真程序产生的结果是固定的,就没有随机性

实现随机性的方法

  1. ns3::RngSeedManager::SetSeed() 更改seed
  2. ns3::RngSeedManager::SetRun() 更改运行标识
  3. 在脚本中使用则是NS_GLOBAL_VALUE=“RngRun=3” ./waf --run xxx (也可以用命令行传递参数)

NS3中的一些编程概念_第1张图片

CALLBACK

也就是使用C++的函数指针,不过ns-3提供了一个Callback

使用方法

  1. 针对静态函数
static double cbone (double a,double b)
{
std::out <<"xxxxxx";
return a;
}
.......
int main()
{  
//Callback 中的一个参数指明函数返回类型,后面的参数指定形参类型 同时也被动指定了形参数量 除了第一个参数外最多还可以有4个参数 如果定义的函数加上返回值超过五个 则需要扩展回调
    Callback one;  //实例化回调类型
    one= MakeCallback(&cbone);  //回调绑定
    one(1,2);  // 相当于cbone(1,2)
    .......
}
  1. 针对类成员函数(则需要给MakeCallBack额外增加一个参数告诉它类名和方法)
class mycb{
public:
int cbtwo (double a) {
  return 1;
}
....
Callback two;
mycb cb;
two=MakeCallback(&mycb::cbtwo,&cb) ;
two(2);  // 相当于 cb->cbtwo(2);
......
}
  1. 构建NULL回调
    ns3允许回调为空, three=MakeNullCallback(); 就不指向任何函数

对象模型

ns-3提供了3个对象基类供用户继承 分别是Object ObjectBase SimpleRefCount
ns-3并不强迫每个类的继承自这3个类,但从这三个基类继承的类包含了ns-3提供的特有特性:

  1. 属性系统
  2. 对象聚合系统
  3. 智能指针和引用计数系统
    ObjectBase中继承的类有前两个功能 SimpleRefCount中继承的类只包含智能指针功能 而Object全都有

ns-3提供CreateObject替代在c++中使用new操作符 不过前提是这个类支持智能指针 这么做可以正确处理智能指针引用计数 方便内存管理

聚合

ns-3使用查询接口设计模式来避免"向下类型转换"和"弱基类"的问题 ns3中任何网络终端都用着相同的Node类 但不同网络终端构件和协议是不同的 这就需要用聚合的方式将不同的构件协议聚合到节点中 以节点聚合网络协议为例:
NS3中的一些编程概念_第2张图片首先创建一个IPV4协议的指针对象,然后把IPV4协议聚合到节点中 现在若用户想要配置节点m_node中的路由协议,就可以通过 Ptr< IPv4 > ipv4= m_node->GetObject< IPv4 >();
值得注意的是,不能将同一类的对象同时聚合,会造成错误(比如往节点放两个路由协议)

属性系统

TypeId

ns-3中所有由Object类派生的类都可以包含一个叫TypeId的元数据类,该类用来记录关于类的元信息,以便在对象聚合以及构建管理中使用 TypeId类中用唯一的字符串来标识一个类\子类的基类\以及子类中可以访问的构造函数
NS3中的一些编程概念_第3张图片SetParent声明该类的基类
AddConstructor为创建对象
AddAttribute则是把一个给定的唯一字符串和类的成员变量相关联,第一个参数是绑定的字符串,第二个参数是对字符串的解释说明,第三个参数是绑定的类成员变量必须转化的类型,第四个参数是把类成员强制转化为第三个参数声明的类型,第五个参数则是检查使用的成员变量是否合法

使用TypeId

如果用户想要对网络模拟中的内部变量进行细致的访问,或者想要广泛地修改某个特定参数的初始值,以便改变随后要创建的对象等等,ns-3就是通过TypeId而不是在类中加入指针来获取


class DropTailQueue : public Queue
{
public: 
static typeId GetTypeId(void);
...
private:
std::queue > m_packets;
uint32_t m_maxPackets;
};

NS3中的一些编程概念_第4张图片上述代码中AddAttribute()对m_maxPackets进行处理如下:

  1. 将其绑定到一个字符串MaxPackets中
  2. 提供默认值100
  3. 提供为该值的解释
  4. 提供checker检查设置的合法性
    之后用户可以通过MaxPackets进行操作

如果要将自定义的类加入到属性系统中,则需要在类中声明函数GetTypeId以及向ns注册自定义的类,例如类名为A: NS_OBJECT_ENSURE_REGISTERED(A);

Tracing系统

Tracing系统由Tracing Sources 和 Tracing Sinks 以及将这两者关联在一起的方法组成
Tracing Sources是一个实体,指示并提供一个途径将分组的内容传递给对该分组感兴趣的Tracing Sink 也可以当其状态发生变化时通告给Tracing Sink 很像JAVA中的监听
Tracing Sources本身不起作用 必须和有实际功能的代码相关联才有意义,这段代码就是Tracing sink
Tracing系统和属性系统相关联 属性系统和对象又相关联 所以追踪的数据必须属于一个特定的类
如:
NS3中的一些编程概念_第5张图片AddTraceSource使得m_myInt成为一个Tracing sources 并且用MyInteger和它绑定
NS3中的一些编程概念_第6张图片上述代码就是一个Tracing sink
NS3中的一些编程概念_第7张图片TraceConnectWithoutContext则是将Tracing sources和Tracing sink关联起来的一个方法
当m_myInt改变的时候 IntTrace函数会调用 输出改变前的值和改变后的值 (并没有具体的指示说明IntTrace方法是如何知道要输出这两者的,应该是ns3在关联二者的时候根据类型定义的行为 这里的Tracing类似于JAVA的监听)

还可以通过配置路径来建立两者的关联
NS3中的一些编程概念_第8张图片在这里插入图片描述(应该是/NodeList/ 截图中漏了个"/")
使用Config的静态成员函数Connect将二者关联 第一个参数是作为路径的字符串 其中第一个"/“代表紧跟的是命名空间 第二个”/“则是类似于目录结构那样理解 这里的命名空间是NodeList 紧随其后的是这个节点列表的一个索引 下一段字符”$"会提醒程序调用GetObject返回一个对象 对象类型就是ns3::MobilityModel 再跟着的就是我们要追踪的属性CoureChange
(话说这玩意也就知道个大概把 还有好多不清楚的呢 先不管了)

你可能感兴趣的:(ns3)