由于毕设需要,才开始接触NS2。现在准备整理下整个过程,估计以后不会用到NS2了。
首先是安装NS2了,笔者用的是NS2.34版本,安装过程有点小麻烦。后来看了下NS2.35的安装过程,都没啥报错,方便多了,大家有需要可以直接安装2.35版本。附上下载链接:
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 essentialsudo apt-get install tcl8.4 tcl8.4-dev tk8.4 tk8.4-dev #for tcl and tksudo 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:相应文件的代码
代码太多了,不贴了,附上下载地址。
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 <caodv/caodv_packet.h>
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: # …
一个能从别人的观念来看事情,能了解别人心灵活动的人,永远不必为自己的前途担心。