NS2入门笔记
1.Tcl和Otcl
1.1 Tcl
Tcl中变量名只使用英文字母,数字和下划线。
反斜杠 转义字符: '\[' , '\$';十六,八进制: '\x31' ,'\24';在行末表示续行。
if语句:if exp1 then body1 elseif exp2 body2 else body3
if{$x >= 0}{
puts "hello!"
}else{
puts "End!"
} #使用花括号方便控制命令延伸到多行,便于阅读。使用双引号在进行组合也是合法的。
switch语句:switch flags value pattern1 body1 pattern2 body2 ...default bodyn
flags: -exact:严格匹配,必须value和pattern值相同才匹配,默认模式。
-glob: 字符串匹配。使用*表示任何字符,使用?表示单个字符。
-regexp:使用正则表达式。
while语句:while boolExpr body
foreach语句:foreeach loopvar valueList body
for语句:for initial test step body
过程proc:proc name params body
指定默认参数:proc p1{a b {c 1}} #参数c具有默认值1
可变参数:proc p2{a {b foo} args} #使用关键字args作为过程最后一个参数。
rename命令:1.拓展一个已经存在的命令。 1.隐藏某些命令:rename puts {} 可以使以后再也不调用puts命令了。
数组:可以使用set命令来定义:set arr(index) value ; 使用unset来删除数组元素和数组。info exist命令检查该元素是否存在。
array命令用法:《NS与网络模拟》 P36,表3.3。
1.2Otcl
类:定义类:%Class Animal ; 产生类:%Animal animal_1;通过info命令查看类和对象的关系:animal info class => Animal , Animal info instances => animal_1
成员变量和成员函数:定义方法关键字:instproc ;定义成员变量关键字:instvar;变量$self 的作用和c++中this类似。
Animal instproc run {speed}{ #定义成员函数
$self instvar speed_ #定义成员变量
set speed_ $speed
puts "...speed $speed_"
}
调用成员函数:object obj_proc vars
成员变量赋值:object set obj_var value
对象的初始化和销毁:采用函数init进行初始化,采用destroy完成析构。
next函数的含义是父类的中同名函数。因此周期init函数中 'eval $self next $args' 显示地调用了父类的init函数。
继承:Otcl中成员变量和函数都是public类型,因此子类可以继承父类所有特性。使用关键字:superclass。
obj info superclass #查看父类信息 obj info heritage #查看继承树信息
2.Tclcl
分裂对象模型中Otcl类称为解释类,c++类称为编译类,他们互为“影像类”。
c++类都是从TclObject一级级继承,所有Otcl类都是从SplitObject一级级继承。NS中使用“/”作为分割符的命名规则来表示一个Otcl类从SplitObject开始继承的关系。
Tclcl通过TclObject和TclClass两个类实现Otcl和C++的关联。类TclClass包含了执行这种印像的机制。
每个解释类必须在初始化实例过程中调用其父类的初始化实例过程,以便最终能够执行到基类SplitObject的初始化实例过程中去创建影像对象。
由于创建影像对象时将进行对象绑定,因此最好调用父类的初始化实例过程要先于当前类的初始化,以便绑定变量能够尽早被创建。
通常用户不用编写初始化实例过程。为成员变量设置初始值的程序段只要写在合适的地方能够被尽早得执行就可以了。NS会循着继承关系自动调用父类的初始化实例过程。
TclClass是个纯虚类:构造和编译类结构互为镜像的解释类结构,初始化新的TclObject方法。每个从TclClass继承出来的类都和编译类中的一个TclObject子类相关联,并能初始化所关联类的新的对象。
通过建立一种双向绑定,使得解释对象的成员变量个编译对象的成员变量都访问相同的数据。NS支持五种数据类型绑定:实数,宽带变量,时间变量,整数,布尔。
语法:bind("Otcl变量","&C++变量引用");
NS通过command()函数实现Otcl对象调用c++对象的方法。过程cmd{}调用影像对象的方法command()。
3.TCL类
类TCL封装Otcl解释器的实例,并提供了访问解释器的方法。获取Tcl类 Tcl& tcl = Tcl::instance();
调用Otcl命令方法: tcl.eval(char* s) #执行字符串s ,并在tcl的结果变量中保存执行结果。
tcl.evalc(const char* s) #先把s存储在命令缓存中,然后再执行。
tcl.eval() #执行命令缓存中的命令。
tcl.evalf(const char* s,...) #类似printf。
返回值:tcl.result() 获取返回值。
设置返回值的方法: tcl.result(const char* s) #把结果字符串s传回解释器
tcl.resultf(const char* s,...)
对象查找:用户能根据对象的名字查找哈希表获得对象的TclObject指针。
TclObject* Tcl::lookup(const char* s) //获取名字为s的TclObject引用
4.NS基础
4.1 事件调度机制
NS是一个事件驱动模拟器,默认采用calendar schedule 调度器。
NS中的Event类有两个派生类:at-events和packets。at-events用来在特定的时间执行特定的命令。
$ns at <time><events> ; $ns use-scheduler Heap
4.2 节点
创建节点:$ns node 。包括两个tcl对象:地址分类的和端口分类器。
配置节点:使用node-config命令设置节点参数。 《NS与网络模拟》 P61。
分类器Classifier:从逻辑上匹配一个分组,并基于匹配结果把该分组传递给相应的对象。
Classifier类实例:alloc-port <null-agent> 寻找一个空闲的slot
clear <index> 将号码为index的slot清空。
installNext <object> 在最后一个slot插入一个新的指向object的表项,并返回slot号码。
slot <index> 查询号码为index的slot对应的对象名。
findslot <object> 查询object所在的slot号码
install <index><object>
4.3 链路
创建单向链路: $ns simplex-link <node> <node2> <bandwidth> <delay> <queue_type> <args>
双向链路:duplex-link 。实际由两条simplex-link组成。
相关命令:$link link 返回$link对象实例变量link_
$link queue 返回实例变量queue_
$link cost <c> 设定链路开销
$link cost? 返回链路开销
$link up 设置链路状态为up ;$link down; $link up? 返回链路状态。
4.4 定时器
c++中的抽象基类Timerhandler;《NS与网络模拟》 P75
Otcl Timer类。《NS_From_China》 P107
4.5 分组头
分组(Packet)是对象间交互的基本单元。分组由一系列的分组头和一个可选的数据空间组成。
去掉某个分组头:remove-packet-header AODV ARP #必须在Simulator对象创建之前。
remove-all-packet-headers #去掉所有分组
add-packet-header IP TCP #不允许去掉common头
4.6 代理
agent代表了网络层分组的起点和终点,并被用于实现如TCP和UDP等网络协议。
UDP代理:set udp0 [new Agent/UDP]
$ns attach-agent <node> <agent>
$cbr0 attach-agent <agent>
$ns connect <src-agent> <dst-agent>
TCP单向代理:set tcp [new Agent/TCP] #TCP发送者
set sink [new Agent/TCPSink] #TCP接受者
$ns attach-agent $n0 $tcp
$ns attach-agent $n1 $sink
$ns connect $tcp $sink
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ns at 1.2 "$ftp start"
4.7 应用层
应用层程序构建在运输层代理之上,分为流量发生器(UDP)和应用模拟器(TCP)两大类。
使用detach-agent 命令将代理和节点分开。
将应用层程序连接到运输层上: set ftp1 [new Application/FTP]
$ftp1 attach-agent $src
也可以简写如下:set ftp1 [$src attach-app FTP]
流量发生器(TrafficGenerator):EXPOO_Traffic , POO_Traffic , CBR_Traffic , Trafic Trace
4.8 无线网络
MobileNode(移动节点)模块由CMU的Monarch工作组引入到NS中。支持的ad-hoc协议包括:DSDV,DSR,TORA,AODV。
创建MobileNode方法:$ns node-config -adhocRouting $opt(adhocRouting)
-llType $opt(ll)
...
移动节点的移动: 方法一:$node set X_ <x1>
$node set Y_ <y1>
$node set Z_ <z1>
$ns at $time $node setdest <x2> <y2> <speed>
方法二:$moblenode start #随机移动
设置平面拓扑的长和宽: set topo [new Topography]
$topo load_flatgrid $(x) $(y)
4.9 trace文件
flush-trace{} 刷新模拟过程中的所有Trace对象的缓存。
create-trace{type file src dst} 在给定的src节点和dst节点间创建类型为type的Trace对象。
trace-queue{n1 n2 file} 设定节点n1和n2间的链路的trace。
trace-callback{ns command} 每当新增一行trace时调用command。参考 ns/tcl/ex/callback_demo.tcl
drop-trace{n1 n2 trace}
5.gawk工具
gawk的主要功能是针对文件的每一行(line)搜寻指定的模式(pattern)。当一行里有符合指定模式时,gawk就会在此一行执行指定动作(action)。
语法:(1)gawk 'program' input-file1 input-file2 #其中program包括pattern和action
(2)gawk -f program-file input-file1 input-file2
(3)gawk -program-file1 program-file2 input-file1 input-file2
gawk的输入可以从标准输入或者指定文件里读取。输入的读取单位被称为记录(record)。记录与记录之间采用默认分割符‘\n’隔开。以空白符将一行分成多栏。
gawk中$0表示整个记录,$1表示记录的第一栏,$2...以此类推。
END{action}匹配:表示在所有输入读完后执行action。 BEGIN{action}表示在第一行被读之前执行一次action。
系统变量: RS 行分割符变量
FS 栏分割符变量
FNR 存储目前的输入档案已经被读取的记录个数。
NR 存储目前为止所有的输入档案已经被读取的记录个数。
打印输出: print intem1,intem2,... ; printf format,intem1,item2,...
匹配模式:(1)正则表达式 /regular exp/ 比较运算 exp ~/regexp/ #若exp符合regexp 则结果为真
exp !~/regexp/
< ,<=,>,>=,==,!=
(2)单一的表达式expression。当一个值不为0或者一个字符串不是空时,则视为匹配。
(3)part1,part2 。一对pattern用逗号分开,指定记录范围。
(4)BEGIN ,END
(5)null 。匹配任意记录。
ACTION运算式:支持+,-,*,、,%运算,x**y表示x的y次方。支持与pattern相同的匹配运算。条件运算:?: 。
ACTION控制语句:和c语言类似。
常用内建函数:《NS与网络模拟》 P134。
自定义函数: function name (parameter-list){
body-of-function
}
6.绘图工具gunplot
gunplot有两种工作方式,交互式方式(在命令行中直接输入gunplot即可),批处理方式。
plot有两种绘图方式:绘制函数,从数据文件中读取数据并进行绘制。
绘制函数:例子:plot [0:10] sin(x) + 0.*x
常用函数:《NS与网络模拟》 P138,表6.1
绘制数据:plot将数据文件中的第一列作为x坐标值,第二列作为y坐标值进行绘制。如:plot 'test.data'
with选项: plot 'test.data' with i 3 #用三号线型画脉冲图
plot 'test,data' w linesp lt 2 pt 3 #用2号线型和3号点阵画电线图
using选项: plot 'test.data' 2:3 #使用第二列作为x轴,第三列为y轴
plot 'test.data' using 0: ($1+$2) '%*lf%lf%*20[\n]%lf'
其中0表示横坐标从0依次递增。纵坐标的值为读入数据第一列和第二列的和。
读入格式: %*lf 忽略一列实数数据
%lf 读入一个实数数据,包括整数
%*20[\n] 忽略ASCII中除回车符以外的数据
此段读入格式含义:忽略第一列数据,读入第二和第三列数据,即对应的$1和$2
同时绘制函数和数据: plot 'test.data' using 1: ($2+$3) title 'data' with lp , x**2
三维绘图:splot [-1:1] [-1:1] (x*x - y*y) / (x*x + y*y)
replot:重复最后一次在gunplot中使用到的plot和splot命令。
图形显示设置: set title 'example' #图形标题
set xrange [1:10] #设置x坐标范围
set xtics 0,0.5,10 #设置坐标刻度显示
对数显示:set xrange [1:10000]
set logscale x
set xtics 1,10,10e4
set key left title 'legend' #设置标题显示位置
set xlabel 'label name' #坐标轴标签
set size 0.5,1 #设置图片大小,按比例修改
set terminal png #设置终端格式
set output plot.png #将输出重定向到文件
7.cbrgen
该工具用来生成传输负载,可以产生TCP流或者CBR流。
注意:默认时间长度为180s 要改就要修改cbrgen.tcl文件
cbrgen程序放在 urs/local/ns2/ns-2.34/indep-utils/cmu-scen-gen/目录下,执行命令
使用方法如下:
ns cbrgen.tcl [-type cbr|tcp] [-nn nodes] [-seed seed] [-mc connections][-rate rate]
-type 表示数据流的类型
-nn 表示节点的数目
seed 表示随机种子数
-mc 表示最大连接数
-rate 表示发送速率,pkt/s
举个例子:ns cbrgen.tcl -type cbr -nn 4 -seed 1 -mc 1 -rate 1.0 > fs.tcl 结果会在cmu-scengen-gen下生成一个名为fs.tcl的文件
8.setdest
拓扑场景生成工具setdest用来生成无线网络所需节点的运动场景,setdest的使用方法是首先make一下
Setdest使用方法让如下:
./setdest -v<1 or 2> -n<nodes> -p<pause time> -m <min speed> M<max speed>-t<simulation time> -x <max_x> -y<max_y>
-v表示setdest的版本
-n表示指定场景中的节点数
-p表示节点停留时间
-m 表示节点的最小移动速度
-M表示节点的最大移动速度
-t 表示仿真时间
-x表示仿真场景的长度
-y 表示仿真场景的宽度
9.threshold
NS中提供了三种传输模型:FreeSpace,TwoRayGround和Shadowing。一个数据包如果要在接收方正确接收,接收功率必须大于某个阈值。此工具可以设置传输模型获取接收功率阈值。
命令格式: threshold -m <paopagation-model> [other-option] diatance
paopagation-model指定了传播模型。distance指定了传输范围。other-option指定了一些参数。
通用参数: -Pt <transmit-power> 指定了发射者的发射功率
-fr <frequency> 指定了发射者的发射频率
-Gt <transmit-antenna-gain> 发射天线的放大率
-L <syatem-loss> 系统丢失率 L>=1。
TwoRayGround特有参数:
-ht <transmit-antenna-height> 发送天线的高度
-hr <receive-antenna-height> 接收天线的高度
例子:./threshold -m TwoRayGround 400
10.nam
nam是基于Tck/Tk的动画显示工具,用于演示网络运行动画。
新建nam: set nf [open out.nam w]
$ns namtrace-all $nf #设定out.nam为输出文件 ,通过namtrace-all将该文件与动画输出联系在一起。
在ns运行结束出添加: $ns at 5.0 "finish"
proc finish{}{
global ns nf
$ns flush-trace
close $nf #清空输出缓存,关nam输出文件
exec nam out.nam & #调用nam来打开out.nam
exit 0
}
nam显示设置: $ns duplex-link-op $n0 $n2 orient right-down #节点2在节点0的右下方
$ns duplex-link-op color "green"
$ns duplex-link-op queuePos 0.5 #队列显示为向上
$ns duplex-link-op label "A"
$ns color 1 Blue
$ns color 2 Red
$cbr0 set fid_1 #给发送源设定流的编号
$cbr1 set fid_2
$node color [color] #设定节点颜色
$node shapr [shape] #设定节点形状
$node label [label] #设置节点名称
$node label-color [lcolor] #设定节点显示名称的颜色
$node label-at [ldirection] #设定名称的显示位置
$node add-mark [name][color][shape] #添加注释
$node delete-mark [name] #删除注释
$ns add-agent-trace $Agent AgentName #显示某个节点上绑定了那些Agent

浙公网安备 33010602011771号