由于毕设需要,才开始接触NS2。现在准备整理下整个过程,估计以后不会用到NS2了。
首先是安装NS2了,笔者用的是NS2.34版本,安装过程有点小麻烦。后来看了下NS2.35的安装过程,都没啥报错,方便多了,大家有需要可以直接安装2.35版本。附上下载链接:http://sourceforge.net/projects/nsnam/files/ns-2/
Ubuntu10.04安装NS2.34
1、更新下系统,在终端输入
sudo apt-get update #更新源列表
sudo apt-get upgrade #更新已安装的包
sudo apt-get dist-upgrade #更新软件,升级系统
2、装几个需要使用的软件包
sudo apt-get install build-essential #for gcc and some essential
sudo apt-get install tcl8.4 tcl8.4-dev tk8.4 tk8.4-dev #for tcl and tk
sudo apt-get install libxmu-dev libxmu-headers #for nam
3、安装NS
拷贝安装包到合适的目录中比如/usr
sudo cp ns-allinone-2.34.tar.gz /usr
cd /usr #到安装目录ls #可以查看该目录下的文件sudo tar -xzf ns-allinone-2.34.tar.gz #解压到当前目录cd ns-allinone-2.34 #进入目录sudo ./install #开始安装
4、开始出现错误了。。。
……(以上省略) make: *** [libotcl.so] 错误 1 otcl-1.13 make failed! Exiting ...
在网上找的解释:gcc 4.0版本以前是用ld -share来生成共享库的,但是到了4.0以上的版本,这个命令改为了gcc -share。在终端里输入gcc -v查看,我的版本是gcc version 4.4.1。
解决方法:
cd /usr/ns-allinone-2.34/otcl-1.13sudo gedit configure.in
把77行的SHLIB_LD="ld -shared",改为SHLIB_LD="gcc -shared",保存退出。然后
sudo gedit configure
按照[2]中的说法,在5518行找,木有。于是Ctrl+F了一下,在6000+行找到了。把SHLIB_LD="ld -shared"改为SHLIB_LD="gcc -shared",保存退出。
cd回到目录ns-allinone-2.34下,重新运行
sudo ./install
顺利完成安装。最后出来提示:
Please put /usr/ns-allinone-2.34/bin:/usr/ns-allinone-2.34/tcl8.4.18/unix:/usr/ns-allinone-2.34/tk8.4.18/unix
into your PATH environment; so that you'll be able to run itm/tclsh/wish/xgraph.
IMPORTANT NOTICES:
(1) You MUST put /usr/ns-allinone-2.34/otcl-1.13, /usr/ns-allinone-2.34/lib, into your LD_LIBRARY_PATH environment variable. If it complains about X libraries, add path to your X libraries into LD_LIBRARY_PATH. If you are using csh, you can set it like: setenv LD_LIBRARY_PATH If you are using sh, you can set it like: export LD_LIBRARY_PATH=
(2) You MUST put /usr/ns-allinone-2.34/tcl8.4.18/library into your TCL_LIBRARY environmental variable. Otherwise ns/nam will complain during startup.
After these steps, you can now run the ns validation suite with cd ns-2.34; ./validate
5、配置环境变量
用cd进入目录/home/hm(hm是我的用户名),然后
sudo gedit .bashrc
在文件末尾加入:
PATH="$PATH:/usr/ns-allinone-2.34/bin:/usr/ns-allinone-2.34/tcl8.4.18/unix:/usr/ns-allinone-2.34/tk8.4.18/unix"
LD_LIBRARY_PATH="/usr/ns-allinone-2.34/otcl-1.13:/usr/ns-allinone-2.34/lib"
TCL_LIBRARY="$TCL_LIBRARY:/usr/ns-allinone-2.34/tcl8.4.18/library"
保存退出(上述内容在安装结束后的提示中有,见粗体部分)。
6、验证
打开一个新终端,输入ns,如果出现%,则说明安装成功。
也可以进入/usr/ns-allinone-2.34/ns-2.34/,输入./validate验证。
到此。上面红色标注的部分记得都要用自己的安装路径替换。
安装结束后,开始进入正题,路由协议仿真。。。
由于我的毕设是做2个协议仿真,AODV、COPE+AODV。
AODV是NS2自带的协议,直接编写tcl仿真脚本就可以了;而COPE+AODV是需要自己添加的新协议。
COPE+AODV是一种基于网络编码的无线路由协议。将网络编码思想应用于无线单播网络通信的方案。COPE方案充分利用无线网络节点的广播特性,用简单的异或算法取代复杂的矩阵运算。COPE是一个机会主义的网络编码,其中每个节点窥探其在传输中的位置,学习它邻居节点的位置,同时探测编码机会,确保接收方可以解码。这种灵活的设计允许COPE有效地支持多个单播流,甚至当发送者和接受者是动态的或者数据流是未知和突发性的。COPE的一个设计目的是保证更高层协议和应用的互操作性。
接下来介绍我在NS2中添加COPE+AODV协议的过程。
step 1:比这里将COPE+AODV协议的名字叫做caodv,以ns2.34平台为例,我们在ns2.34目录下建立一个caodv目录。此目录包含caodv.h,caodv.cc,caodv_packet.h,caodv_rtable.h,caodv_rtable.cc五个文件。
其中五个文件的具体功能和作用如下:
(1)caodv.h 定义必要的计时器和路由代理
(2)caodv.cc 执行计时器、路由代理和Tcl文件
(3)caodv_packet.h 声明caodv路由协议需要在无线自组网节点交换的数据包
(4)caodv.h 声明我们自己的路由选择表
(5)caodv.cc 执行路由选择表
step 2:相应文件的代码
代码太多了,不贴了,附上下载地址。
http://download.csdn.net/detail/maple1149/7151821
step 3:我们需要对ns2中的一些文件进行修改,来使这个协议在tcl中被调用,
需要修改的文件有以下几个,你可以在ns目录下找到它们:
Common/packet.h
Trace/cmu-trace.h
Trace/cmu-trace.cc
Tcl/lib/ns-packet.tcl
Tcl/lib/ns-default.tcl
Tcl/lib/ns-lib.tcl
Queue/priqueue.cc
Makefile
step4:需要修改的具体内容(在需要修改的地方添加红色的字)
1.Common/packet.h (两个需要修改的地方)
1: enum packet_t {
2: PT_TCP,
3: PT_UDP,
4: PT_CBR,
5: /* ... much more packet types ... */
6: PT_CAODV,
7: PT_NTYPE // This MUST be the LAST one
8: };
=======================================
1: p_info() {
2: name_[PT_TCP]= "tcp";
3: name_[PT_UDP]= "udp";
4: name_[PT_CBR]= "cbr";
5: /* ... much more names ... */
6: name_[PT_CAODV]= "caodv";
7: }
2.Trace/cmu-trace.h (一个)
1: class CMUTrace : public Trace {
2: /* ... definitions ... */
3: private:
4: /* ... */
5: void format_aodv(Packet *p, int offset);
6: void format_caodv(Packet *p, int offset);
7: };
3.Trace/cmu-trace.cc (三个,先在最上面加头文件,在找一个合适的地方加函数)
1: #include
2:
3: /* ... */
4:
5: void
6: CMUTrace::format_caodv(Packet *p, int offset)
7: {
//这里面的代码可以参考自带的CMUTrace::format_aodv(Packet *p, int offset)
//将里面的aodv全部改成caodv
8: }
=========================================
1: void
2: CMUTrace::format(Packet* p, const char *why)
3: {
4: /* ... */
5: case PT_PING:
6: break;
7:
8: case PT_CAODV:
9: format_caodv(p, offset);
10: break;
11:
12: default:
13: /* ... */
14: }
4.Tcl/lib/ns-packet.tcl(一个)
1: foreach prot {
2: CAODV
3: AODV
4: ARP
5: # ...
6: NV
7: } {
8: add-packet-header $prot
9: }
5.Tcl/lib/ns-lib.tcl(两个)
1: Simulator instproc create-wireless-node args {
2: # ...
3: switch -exact $routingAgent_ {
4: CAODV{
5: set ragent [$self create-caodv-agent $node]
6: }
=======================================
1: Simulator instproc create-caodv-agent { node } {
2: # Create CAODV routing agent
3: set ragent [new Agent/CAODV[$node node-addr]]
4: $self at 0.0 "$ragent start"
5: $node set ragent_ $ragent
6: return $ragent
7: }
6.Queue/priqueue.cc(一个)
1: void
2: PriQueue::recv(Packet *p, Handler *h)
3: {
4: struct hdr_cmn *ch = HDR_CMN(p);
5:
6: if (Prefer_Routing_Protocols) {
7:
8: switch(ch->ptype()) {
9: case PT_DSR:
10: case PT_MESSAGE:
11: case PT_TORA:
12: case PT_AODV:
13: case PT_CAODV:
14: recvHighPriority(p, h);
15: break;
7.Makefile(一个)
1: OBJ_CC = \
2: tools/random.o tools/rng.o tools/ranvar.o common/misc.o common/timer-handler.o \
3: # ...
4: aodv/aodv_logs.o aodv/aodv.o \ aodv/aodv_rtable.o aodv/aodv_rqueue.o \ caodv/caodv_logs.o caodv/caodv.o \ caodv/caodv_rtable.o caodv/caodv_rqueue.o \
5: # ...
6: $(OBJ_STL)
7.tcl/lib/ns-mobilenode.tcl(这个文件修改是为了设置caodv协议的混杂模式,如果往NS2添加的新协议不需要混杂模式就不需要修改了)
这里修改2个地方,加红部分
大约在169行:
Node/MobileNode instproc add-target { agent port } { $self instvar dmux_ imep_ toraDebug_mac_
set ns [Simulator instance] set newapi [$ns imep-support]
$agent set sport_ $port
....
# Special processing for AODV
set aodvonly [string first "AODV" [$agent info class]]
if {$aodvonly != -1 } {
$agent if-queue [$self set ifq_(0)] ;# ifq between LL and MAC
}
# Special processing for CAODV
set caodvonly [string first "CAODV" [$agent info class]]
if {$caodvonly != -1 } {
$agent if-queue [$self set ifq_(0)] ;# ifq between LL and MAC
$agent install-tap $mac_(0)
}
step 5:编译
在ns目录下输入下名命令进行编译:
$ make clean
$ touch common/packet.cc
$ make
到这里,我们添加新协议的过程就结束了。
不过这里还要做一个操作,在ns2.34目录下 cp ns /usr/bin
本来编译完成后,我在做caodv仿真时一直报错,将ns拷贝过去后就没问题了。
大家可以参考:
http://www.baisi.net/thread-3004111-1-35.html里面的回复部分。
step 6:仿真脚本
仿真脚本可以根据需要编写,大家可以参考《NS2网络模拟和协议仿真》(黄化吉)这本书。仿真部分的tcl脚本蛮详细的。
我用的仿真脚本:
运行这个脚本还需要2个文件cbr1和scence1,这2个是设置网络仿真场景的,比如数据发送速率等等。
如何生成:
(1) 利用NS工具cbrgen.tcl生成业务场景文件,在ns-2.34/indep-utils/cmu-scen-gen目录下输入命令: ns cbrgen.tcl –type cbr –nn 50 –seed 1 –mc 10 –rate 2.0 >cbr1
该命令创建了一个具有50个移动节点、10对通信连接、每秒钟发送两个分组的以CBR为业务源的通信场景文件cbr1。
(2)利用NS工具setdest生成移动场景文件,在ns-2.34/indep-utild/cum-scen-gen/setdest目录下输入命令:
./setdest –n 50 –p 0 –M 20 –t 300 -x 1000 –y 300 >scence1 #注意setdest 各个参数含义
该命令创建一个具有50个节点、节点在每个地点停留0秒(即不停留)、最大移动速度20m/s,仿真时间300秒,长1000米,宽300米的移动场景文件scence1
生成后将这2个文件和aodv.tcl脚本放在一起。然后 ns aodv.tcl 就可以了。
这个脚本用起来有点麻烦,大家有能力可以自己写下。。
aodv.tcl
set val(chan) Channel/WirelessChannel
set val(prop) Propagation/TwoRayGround
set val(netif) Phy/WirelessPhy
set val(mac) Mac/802_11
set val(ifq) Queue/DropTail/PriQueue
set val(ll) LL
set val(ant) Antenna/OmniAntenna
set val(ifqlen) 50
set val(nn) 50
set val(rp) AODV #可以改成CAODV就是仿真cope+aodv了
set opt(cp) "cbr1"
set opt(sc) "scence1"
puts "\n"
puts "Simulation of a simple wireless topology running with CAODV\n"
puts "Starting simulation...\n"
set ns_ [new Simulator]
set tracefd [open caodv.tr w]
$ns_ use-newtrace
$ns_ trace-all $tracefd
set namtracefd [open caodv.nam w]
$ns_ namtrace-all-wireless $namtracefd 1000 300
set topo [new Topography]
$topo load_flatgrid 1000 300
set god_ [new God]
create-god $val(nn)
$ns_ node-config -adhocRouting $val(rp) \
-llType $val(ll) \
-macType $val(mac) \
-ifqType $val(ifq) \
-ifqLen $val(ifqlen) \
-antType $val(ant) \
-propType $val(prop) \
-phyType $val(netif) \
-channelType $val(chan) \
-topoInstance $topo \
-agentTrace ON \
-routerTrace ON \
-macTrace OFF \
-movementTrace OFF \
for {set i 0} {$i < $val(nn)} {incr i} {
set node_($i) [$ns_ node]
$node_($i) random-motion 0
}
puts "Loading connection pattern file\n"
source $opt(cp)
puts "Connection pattern file loading complete...\n"
puts "Loading scenario file...\n"
source $opt(sc)
puts "Scenario file loading complete...\n"
puts "Simulation may take a few minutes...\n"
puts "A sample script runs"
#ÉèÖÃÔÚnamÖÐÒƶ¯œÚµãÏÔÊŸµÄŽóС£¬·ñÔò£¬namÖÐÎÞ·šÏÔÊŸœÚµã
for {set i 0} {$i < $val(nn)} {incr i} {
$ns_ initial_node_pos $node_($i) 20
}
for {set i 0} {$i < $val(nn)} {incr i} {
$ns_ at 50.1 "$node_($i) reset"
}
$ns_ at 50.2 "stop"
$ns_ at 50.3 "puts\¡±Simulation runs sucessfully and NS exiting¡\"; $ns_ halt"
proc stop {} {
global ns_ tracefd namtracefd
$ns_ flush-trace
close $tracefd
close $namtracefd
exec nam caodv.nam &
exit 0
}
puts $tracefd "Here is a trace for simple wireless simulation\n"
puts $tracefd "The nodes movement file is $opt(cp)\n"
puts $tracefd "The traffic flow between nodes is $opt(sc)\n"
$ns_ run
step 7:仿真结果tr文件分析
对于仿真生成的tr文件,可用awk脚本处理。我这里只分析协议的吞吐量
awk文件使用方法:awk -f throughout.awk aodv.tr
throughout.awk源代码
#mythroughout.awk
BEGIN{
highest_packet_id = 0;
duration_total = 0;
first_received_time=0;
first = 0;
end = 0;
total = 0;
}
$0~/^r.*AGT/{
receives++;
}
{
time = $3;
packet_id = $41;
packet_size = $37;
if(($1 == "r")&&($19 == "AGT")&&(end_time[packet_id]==0))
{
end_time[packet_id] = time;
if(first == 0)
{
first_received_time=time;
first = 1;
}
total += packet_size *8 ;
end = time;
}
}
END{
#printf(" avg througput:%f bps/s\n", total / (end - first_received_time));
total = (total/(end-first_received_time))/1024;
printf("throughout:%d Kb/s \n",total);
}
得出的数据,可以用MATLAB或者ns2自带的gnuplot来处理。
附上完整代码下载地址:
http://download.csdn.net/detail/maple1149/7151821
参考资料:
http://blog.tianya.cn/blogger/post_read.asp?BlogID=2888395&PostID=30920127
http://www.baisi.net/thread-3004111-1-35.html
http://blog.sina.com.cn/s/blog_49f287820100x4tv.html
http://blog.163.com/heloyure@126/blog/static/643775762012010943795/
http://www.cnblogs.com/haivey/archive/2012/06/29/2570511.html