NS2原理

简介: NS原理概述 离散事件模拟引擎 NS的核心部分是一个离散事件模拟引擎。其中有一个Scheduler类,用来记录当前系统时间,调度网络队列中的事件,并调用其他函数产生新的事件,指定新事件的时间。
NS原理概述
离散事件模拟引擎
NS的核心部分是一个离散事件模拟引擎。其中有一个Scheduler类,用来记录当前系统时间,调度网络队列中的事件,并调用其他函数产生新的事件,指定新事件的时间。
丰富的构件库
NS愿意是针对网络进行模拟的。其中构件涵盖了对网络实体的模拟,包括链路,队列,分组,节点等。构件库易于组合和扩展。支持广域网,局域网,移动通信网络和卫星网络的模拟。
分裂对象模型
NS采用C++和OTcl进行组合编程。其中底层的实体类用C++语言实现,同时有一个OTcl类与之对应,用来配置对象,组合,描述模拟过程并调用NS完成模拟过程。这种将NS中一个构件用两个不同语言的类来实现的方式,叫做分裂对象模型。那么C++对象和OTcl对象之间如何关联呢?通过TclCl机制来实现。
C++具有较高的执行效率,而OTcl是解释性语言,可以在修改配置后不用重新编译,兼顾效率和灵活性。OTcl可以将多个C++对象组合或者扩展成为一个实体对象,如一个节点对象可能包括,业务对象和链路对象等。
采用NS进行模拟的过程
如果利用NS中已有组件进行开发,只需要编写OTcl脚本即可。如果没有需要的模块,就要对NS就行扩展,重新编写您需要的C++类和OTcl类。
  1. 编写脚本文件。配置网络的Top结构,此时可以配置链路特性,延时,带宽,丢失策略等。
  2. 建立协议代理,包括绑定端设备的协议和建立通信量业务模型。
  3. 配置业务参数
  4. 设置Trace对象,跟踪记录特定时间,模拟完成后可以对其进行分析得到结果。
  5. 编写其他辅助过程,并设定时间。
  6. 执行模拟

  Otcl和C++之间的关系

所有的C++类都继承自TclObject,所有的Tcl类都继承自SplitObject。当使用如下命令创建一个Tcl对象时

set ns [new Simulator]
创建一个新的Simulator解释器对象,同时执行继承关系中所有Tcl类的初始化函数init,然后在最高一级的Tcl类SplitObject类中有一个create-shadow函数用来创建的影像类。所以如果自己扩展NS,在Tcl类继承关系中,首先调用父类的初始化函数
proc init {args} {
$self next $args
#进行自己的工作
}
其中,args可以用来传递绑定变量。
注意,只有在Otcl中创建对象时才会创建影像对象,如果直接new C++ Class是不会产生影像对象的。
Otcl的new  delete函数在$NS_HOME\tclcl(版本)\tcl-object.tcl中定义。
 
create-shadow如何知道要创建的影像对象属于那个C++类呢?在TclClass纯虚类中,实现了两个功能:
构造和编译类互为镜像的解释器类结构;提供初始化新TclObject的方法。
每一个继承自TclClass的类都和一个TclObject的子类相关联,并在其中提供create方法用来创建一个新的TclObject子类。
static class RenoTcpClass:public TclClass {
public:
RenoTcpClass():TclClass("Agent/TCP/Reno") {}
TclObject* create(int argc,const char* const* argv) {
return (new RenoTcpAgent());
}
}
在基类TclClass的构造函数中指明了对应的解释类为Agent/TCP/Reno,同时创建编译类RenoTcpAgent。这就像建立了一个映射关系,当OTcl试图创建一个解释器对象Agent/TCP/Reno时,就会调用create函数创建编译对象RenoTcpAgent。
这样所有的Otcl类都在TclClass中得到声明和继承关系。
 
绑定变量
在解释对象和编译对象之间绑定变量,这在编译对象的构造函数中实现。NS支持绑定5中不同类型的变量
Agent::Agent() {
bind("var",&var);
...
}
为不同类型的变量赋值方法不一样,需要指明对应的变量类型。
$object set typevar  value
 
Otcl对象如何调用C++对象的方法?
NS通过command()函数实现。对每个TclObject,NS为其解释对象创建一个实例过程或者函数,cmd()。cmd()调用影像对象的方法command(),并将cmd的参数传递给command()方法。
创建一个解释器对象->创建一个编译对象->绑定变量(使得可以在Otcl中修改编译对象的属性)->调用command()方法(如果在执行解释命令时,无法在解释对象中找到相关方法就会调用对应编译对象的command()方法,实现调用编译对象的函数)
 
在Tcl和TclObject类中,定义了一些static函数,可以用来查找已经定义过的TclObject对象,获得其指针对其操作。
TclObject* Tcl::lookup(const char* s);
TclObject* TclObject::lookup(const char* s);
 
嵌入EmbeddedTcl类
它的作用是储存和执行一段Otcl脚本
void EmbeddedTcl::load() {
Tcl::instance.evalc(code_);
}
 
目录
相关文章
|
存储 Perl
Verilog读书笔记---数据类型、系统任务、`define、parameter、localparam三者的区别
Verilog读书笔记---数据类型、系统任务、`define、parameter、localparam三者的区别
353 0
Verilog读书笔记---数据类型、系统任务、`define、parameter、localparam三者的区别
|
中间件 容器
【TP5.1】配置解释大全
【TP5.1】配置解释大全
145 0
【TP5.1】配置解释大全
|
存储 网络协议 安全