要实现简单的路由协议: 就是按照你的要求从节点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_就能传给nid4)在写了新的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 ' procedureproc 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转载于:https://www.cnblogs.com/ManMonth/archive/2011/03/15/1985518.html
相关资源:基于NS2的AdHoc网络路由仿真研究