NS2上实现一个简单的路由协议

NS2版本:2.34

要实现简单的路由协议: 就是按照你的要求从节点1发到节点2在从节点2发到节点3,我修改的是node节点的addr-classifier功能,因为addr-classifier是负责包的转发功能。所有的数据都是通过addr-classifier转发出去或者转发给上层协议。用port-classifier也可以实现类似功能,但是在仿真的时候不能加入数据比如ftp数据。最后还是要在addr-classifier中对数据进行处理。

以下是执行步骤:          
1)  首先在route-proto.tcl添加一个路由simple 什么事情都不做。

 

加入办法为:

 

1  Class Agent/rtProto/simple -superclass Agent/rtProto
2  Agent/rtProto/simple proc init-all args { }

 

加入的位置大家可以观察一下其他类似的语句,那些是其他协议的句子

使用时要记得在仿真脚本加入$ns rtproto simple  //这个在后面仿真的tcl文件会看到,现在不用管它

2)之后就是修改classifier的功能了。要把收到的包按照你的要求转发。
我定义新的文件为classifier-ants.h和.cc放在文件ns-2.34/classifier里
classifier-ants.h文件为:

#include  " classifier.h "
class  AntsClassifier : public  Classifier {
public :
        AntsClassifier();
        
void  recv(Packet *  p, Handler * h); // 处理接收的报文
         int  nid; // 节点对应的编号,在ns2里节点是从0开始逐一编号的,在对应的tcl脚本有定义
};

 

classifier-ants.cc文件为:

#include  " classifier.h "
#include 
" classifier-ants.h "
static   class  AntsClassifierClass :  public  TclClass {
public :
    AntsClassifierClass() : TclClass(
" Classifier/Ants " ) {}
    TclObject
*  create( int const   char * const * ) {
        
return  ( new  AntsClassifier());
    }
} class_ants_classifier;
AntsClassifier::AntsClassifier()  {   bind(
" tid_ " , & nid);}
void  AntsClassifier::recv(Packet *  p, Handler * h){
  NsObject
*  node  =  NULL;
  Tcl
&  tcl  =  Tcl::instance();
       
if (nid == 0 )
          {  
       tcl.evalf(
" [Simulator instance] get-link-head %d %d " , 0 , 1 ); // [Simulator instance]获取当前实例
        node =  (NsObject * )TclObject::lookup(tcl.result()); // 获取链路0-1对象的指针
            node -> recv(p,h);}
  
if (nid == 1 )         {            tcl.evalf( " [Simulator instance] get-link-head %d %d " , 1 , 3 );
            node
=  (NsObject * )TclObject::lookup(tcl.result());
            node
-> recv(p,h); }
       
if (nid == 3 )
        {
           free(p);
        }
}

仿真时我设置了4个节点 0,1,2,3 功能是0发给1,1发给3.
在这里tid_是相对应的节点的节点号,要从tcl获得,但是对应的classifier没有这个变量
要从node的id_获得的,所以用bind进行绑定,要注意的是节点获得id号之后id_才赋值了,
3)在这里我添在ns-node.tcl文件的
$self nodeid $id_    ;# Propagate id_ into c++ space语句之后,加入

Classifier / Ants  set  tid_ $id_


就能把id_的值传给tid_了,之后bind就能把tid_就能传给nid

4)在写了新的classifier功能后要记得在ns-rtmodule.tcl注册,因为修改classifier是修改module模块
加上:
 

RtModule / Ants instproc register { node } {
    $self next $node
    $self instvar classifier_
    
set  classifier_ [ new  Classifier / Ants]
    $node install
- entry $self $classifier_
 }

5)当然还要在rtmodule.h和rtmodule.cc修改。在rtmodule.h上加上:

class  AntsRoutingModule :  public  RoutingModule {
public :
    AntsRoutingModule() : RoutingModule() {}
    
virtual   const   char *  module_name()  const  {  return   " Ants " ; }
    
virtual   int  command( int  argc,  const   char * const *  argv);
protected :
    AntsClassifier 
* classifier_;
};

这一段代码的位置参照类似代码的位置添加即可

注:这里还要加上头文件

#include  " classifier-ants.h "

不然会出现编译错误。

6)rtmodule.cc加上

static   class  AntsRoutingModuleClass :  public  TclClass {
public :
     AntsRoutingModuleClass() : TclClass(
" RtModule/Ants " ) {}
    TclObject
*  create( int const   char * const * ) {
        
return  ( new  AntsRoutingModule);
    }
} class_ants_routing_module;

接着加上:

int  AntsRoutingModule::command( int  argc,  const   char * const *  argv) {
    Tcl
&  tcl  =  Tcl::instance();
    
if  (argc  ==   3 ) {
        
if  (strcmp(argv[ 1 ] ,  " route-notify " ==   0 ) {
            Node 
* node  =  (Node  * )(TclObject::lookup(argv[ 2 ]));
            
if  (node  ==  NULL) {
                tcl.add_errorf(
" Invalid node object %s " , argv[ 2 ]);
                
return  TCL_ERROR;
            }
            
if  (node  !=  n_) {
                tcl.add_errorf(
" Node object %s different from n_ " , argv[ 2 ]);
                
return  TCL_ERROR;
            }
            n_
-> route_notify( this );
            
return  TCL_OK;
        }
        
if  (strcmp(argv[ 1 ] ,  " unreg-route-notify " ==   0 ) {
            Node 
* node  =  (Node  * )(TclObject::lookup(argv[ 2 ]));
            
if  (node  ==  NULL) {
                tcl.add_errorf(
" Invalid node object %s " , argv[ 2 ]);
                
return  TCL_ERROR;
            }
            
if  (node  !=  n_) {
                tcl.add_errorf(
" Node object %s different from n_ " , argv[ 2 ]);
                
return  TCL_ERROR;
            }
            n_
-> unreg_route_notify( this );
            
return  TCL_OK;
        }
    }
    
return  (RoutingModule::command(argc, argv));
}

以上两段代码的位置同样参照其他协议类似代码的位置
7)之后在ns-node.tcl

Node  set  module_list_ { Base }

修改为 

Node  set  module_list_ { Ants }

注:这个修改完以后,除了我们现在这个使用这个协议的tcl例子可用外,其他我们原来的仿真例子均不可用了。

      因此做完这个实验要把这个改回来。(很重要,我是新手,自己调试的时候郁闷死我了)

8)最后在Makefile里面的OBJ_CC加上

classifier / classifier - ants.o

 

 

附tcl脚本:

set  ns [ new  Simulator]
 
$ns rtproto simple 
 
set  nf [open  out .nam w]
$ns namtrace
- all $nf
 
#Define a 
' finish '  procedure
proc finish {} {
        
global  ns nf
        $ns flush
- trace
        #Close the NAM trace file
        close $nf
        #Execute NAM on the trace file
        exec nam 
out .nam  &
        exit 
0
}
 
#Create four nodes
set  n0 [$ns node]
set  n1 [$ns node]
set  n2 [$ns node]
set  n3 [$ns node]
 
#Create links between the nodes
$ns duplex
- link $n0 $n1 2Mb 10ms DropTail
$ns duplex
- link $n0 $n2 2Mb 10ms DropTail
$ns duplex
- link $n1 $n3 2Mb 10ms DropTail
$ns duplex
- link $n2 $n3 2Mb 10ms DropTail
 
set  udp [ new  Agent / UDP]
$ns attach
- agent $n0 $udp
set   null  [ new  Agent / Null]
$ns attach
- agent $n3 $ null
$ns connect $udp $
null
#Setup a CBR over UDP connection
set  cbr [ new  Application / Traffic / CBR]
$cbr attach
- agent $udp
$cbr 
set  type_ CBR
$cbr 
set  packet_size_  1000
$cbr 
set  rate_ 1mb
$cbr 
set  random_  false
 
  #Schedule events 
for  the CBR and FTP agents
$ns at 
0.1   " $cbr start "
$ns at 
4.5   " $cbr stop "
 
$ns at 
5.0   " finish "
$ns run


学习ns2一定要用tcl-debug和gdb 用这2个工具能很容易解决学习上遇到的问题,对运行原理有深刻的了解cl////

注:因为我按照原文做的过程中遇到了一些小错误,我在原文的基础上已经做了更正。

原文:http://blog.sina.com.cn/s/blog_570d8e0f0100i3ic.html

你可能感兴趣的:(实现)