NS2:tcl 脚本运行时的流程,调用的类和函数

来源:互联网 发布:淘宝打假吃货仅退款 编辑:程序博客网 时间:2024/06/02 04:18

一般的方法都是在 C++ 中定义的 , OTcl 一般通过 unknown{}, cmd{}, 调用 C++  comand{}, 然后在调用到 C++ 的方法而直接在 Otcl 中定义方法的情况比较少见 , 但也不是没有。

 tcl 脚本运行时的流程:

set val(proc) 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(rp) DSDV

1、set ns_ [new Simulator]

(一)#tcl代码:

#ns-lib.tcl

#  Class Simulator 方法 Simulator instproc init args

#没有找到解释层次的Simulator,只在ns-lib.tcl(Aqua-Sim-1.0\ns-2.30\tcl\lib)Line128看到”#Class Simulator”

##Class Simulator

#...

#Simulator instproc init args {}

(二)#C++代码:

#Simulator.{h.cc}

# class Simulator,class SimulatorClass方法Simulator()

#class Simulator : public TclObject {}

#static class SimulatorClass : public TclClass {

#public:

#       SimulatorClass() : TclClass("Simulator") {}

#       TclObject* create(int argc, const char*const* argv) {

#                return (new Simulator);

#       }

#

#} simulator_class;

#

#      Simulator() : nodelist_(NULL), rtobject_(NULL), nn_(0), /

#       size_(0) {}

 

2、set topo [new Topography]

#tcl代码:找不到

#C++代码:

#topography.{h.cc}

#class Topography,class TopographyClass方法Topography()

#class Topography : public TclObject {}

#

#static class TopographyClass : public TclClass {

#public:

#        TopographyClass() : TclClass("Topography") {}

#        TclObject* create(int, const char*const*) {

#                return (new Topography);

#        }

#} class_topography;

# Topography() { maxX = maxY = grid_resolution = 0.0; grid = 0; }


3、$topo load_flatgrid 700 700     

#tcl代码:

# topography.cc

#Otcl的类是小于C++的类,这个tcl的实现是用unknown{},cmd{},command{}实现的

#int

#Topography::command(int argc, const char*const* argv)

#{

#       …

#       else if(argc == 4) {

#                if(strcmp(argv[1], "load_flatgrid") == 0) {

#                          if(load_flatgrid(atoi(argv[2]), atoi(argv[3])))

#                                   return TCL_ERROR;

#                          return TCL_OK;

#                }

#       }

#       else if(argc == 5) {

#                if(strcmp(argv[1], "load_flatgrid") == 0) {

#                          if(load_flatgrid(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])))

#                                   return TCL_ERROR;

#                          return TCL_OK;

#                }

#       }

#       return TclObject::command(argc, argv);

#}

#C++代码:

#topography.{h.cc}

#方法load_flatgrid ()

#int

#Topography::load_flatgrid(int x, int y, int res)

#{

#       /* No Reason to malloc a grid */

#

#       grid_resolution = res;      // default is 1 meter

#       maxX = (double) x;

#       maxY = (double) y;

#

#       return 0;

#}


4、set f [open 2-2.tr w]

#tcl代码:

#ns-lib.tcl

#方法trace-all

#Simulator instproc trace-all file {

#       $self instvar traceAllFile_

#       set traceAllFile_ $file

#}

#C++代码:


5、$ns_ trace-all $f

#tcl代码:

#ns-lib.tcl

#方法eventtrace-all

#Simulator instproc eventtrace-all {{file ""}} {

#       $self instvar eventTraceAll_ eventtraceAllFile_ traceAllFile_

#       set eventTraceAll_ 1

#       if {$file != ""} {

#                set eventtraceAllFile_ $file

#       } else {

#                set eventtraceAllFile_ $traceAllFile_

#       }

#      

#}

#C++代码:


6、$ns_ eventtrace-all

    set nf [open 2-2.nam w]

    $ns_ namtrace-all-wireless $nf

#tcl代码:

#ns-lib.tcl

#方法namtrace-all-wirelessnamtrace-all

#Simulator instproc namtrace-all-wireless {file optx opty} {

#        $self instvar namtraceAllFile_

#

#       # indicate that we need a W event written to the trace

#       $self set namNeedsW_ 1

#       if { $optx != "" && $opty != "" } {

#                $self set namWx_ $optx

#                $self set namWy_ $opty

#       }

#

#       $self namtrace-all $file

#}

#Simulator instproc namtrace-all file   {

#       $self instvar namtraceAllFile_

#       if {$file != ""} {

#                set namtraceAllFile_ $file

#       } else {

#                unset namtraceAllFile_

#       }

#}

#C++代码:


7、create-god 2

#tcl代码:

#com.tcl

#类Class God方法create-god{}

##Class God

#proc create-god { nodes } {

#       #global ns_ god_ tracefd

#       set god [God info instances]

#       if { $god == "" } {

#                set god [new God]

#       }

#       $god num_nodes $nodes

#       return $god

#}

#C++代码

#god.{h,cc}

#class God,class GodClass

#数值2通过com.tcl中的num_nodes传给god.cc中的int num_nodes

# class God : public BiConnector {}

# static class GodClass : public TclClass {

#public:

#        GodClass() : TclClass("God") {}

#        TclObject* create(int, const char*const*) {

#                return (new God);

#        }

#} class_God;


8、    $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 Channel/WirelessChannel/

         -topoInstance $topo/

         -agentTrace ON/

         -routerTrace OFF/

         -macTrace ON/

         -movementTrace OFF

#tcl代码:

#ns-lib.tcl

#方法node-config

#Simulator instproc node-config args {

#                …

#        set args [eval $self init-vars $args]

#                ...

#}

#C++代码:没有或者我不知道我觉得是把每个变量的值用变量绑定的用法传给对应的C++中的变量


9、set node_(0) [$ns_ node]

     set node_(1) [$ns_ node]

(1)#tcl代码:

#ns-lib.tcl; ns-mobilenode.tcl

#方法node; create-wireless-node; create-node-instance Node/MobileNode方法init

# Simulator instproc node args {

#       …     

#       # wireless-ready node

#       if { [info exists routingAgent_] && ($routingAgent_ != "") } {

#                set node [eval $self create-wireless-node $args]

#                …

#                return $node

#       }

#       …     

#}

# Simulator instproc create-wireless-node args{

#       …

#       set node [eval $self create-node-instance $args]

#       …

#}

#

# Simulator instproc create-node-instance args {

#       …

#       else {

#                set nodeclass Node/MobileNode

#       }

#       return [eval new $nodeclass $args]

#}

#Node/MobileNode instproc init args {

#       …

#       eval $self next $args

#       …

#}

(2)#C++代码:

#mobilenode.{h,cc}

#class MobileNode,class MobileNodeClass方法MobileNode(void)

# class MobileNode : public Node {}

#

# static class MobileNodeClass : public TclClass {

#public:

#        MobileNodeClass() : TclClass("Node/MobileNode") {}

#        TclObject* create(int, const char*const*) {

#                return (new MobileNode);

#        }

#} class_mobilenode;

# MobileNode::MobileNode(void) : pos_handle_(this){}


10、$node_(0) label "Node 0"

$node_(0) set X_ 10.0

$node_(0) set Y_ 10.0

$node_(0) set Z_ 0.0

 

$node_(1) label "Node 1"

$node_(1) set X_ 600.0

$node_(1) set Y_ 600.0

$node_(1) set Z_ 0.0

(1)#tcl代码:

#tcl中没有label方法,然后我去查看对应的C++中的command方法,但是没有查到,凭感觉是调用C++中的Node::label(),不过没有找到如何使Node::label()运行的command方法

(2)#C++代码:

#node.cc,方法label()

#void

#Node::label(const char* name, int anchor) {

#       delete []label_;

#       label_ = new char[strlen(name) + 1];

#       strcpy(label_, name);

#       anchor_ = anchor;

#}


11、set udp1 [new Agent/UDP]

(1)#tcl代码:无

(2)#C++代码:udp.{h,cc}

#class UdpAgent,class UdpAgentClass方法UdpAgent(){}

# class UdpAgent : public Agent {}

#static class UdpAgentClass : public TclClass {

#public:

#       UdpAgentClass() : TclClass("Agent/UDP") {}

#       TclObject* create(int, const char*const*) {

#                return (new UdpAgent());

#       }

#} class_udp_agent;


#UdpAgent::UdpAgent() : Agent(PT_UDP), seqno_(-1)

#{

#       bind("packetSize_", &size_);

#}


12、set null1 [new Agent/Null]

(1)#tcl代码:

#ns-agent.tcl

#Class Agent/Null,方法Agent/Null instproc init args{}

# Class Agent/Null -superclass Agent

#Agent/Null instproc init args {

#    eval $self next $args

#}

(2)#C++代码没有,Otcl中的Agent/Null继承于Agent,调用C++中类Agent的初始化


13、$ns_ attach-agent $node_(0) $udp1

       $ns_ attach-agent $node_(1) $null1

(1)#tcl代码:

(2)#C++代码:没有

#ns-lib.tcl, ns-node.tcl

#方法attach-agent{},方法attach{},方法add-target

# Simulator instproc attach-agent { node agent } {

#       $node attach $agent

#       …

#}

#Node instproc attach { agent { port "" } } {

#       …

#       $self add-target $agent $port

#}

# Node instproc add-target { agent port } {}


14、$ns_ connect $udp1 $null1 

(1)#tcl代码:

#ns-lib.tcl

#方法connect{}方法simplex-connect{}

#Simulator instproc connect {src dst} {

#       …

#       $self simplex-connect $src $dst

#       $self simplex-connect $dst $src

#       …

#}


#Simulator instproc simplex-connect { src dst } {

#       …

#       return $src

#}

#

(2)#C++代码:没有


15、set cbr1 [new Application/Traffic/CBR]

(1)#tcl代码:找不到

(2)#C++代码:

#cbr_traffic.{h,cc}

#class CBR_Traffic,class CBRTrafficClass,方法CBR_Traffic()

# class CBR_Traffic : public TrafficGenerator {}

#

#static class CBRTrafficClass : public TclClass {

# public:

#       CBRTrafficClass() : TclClass("Application/Traffic/CBR") {}

#       TclObject* create(int, const char*const*) {

#                return (new CBR_Traffic());

#       }

#} class_cbr_traffic;

#CBR_Traffic::CBR_Traffic() : seqno_(0)

#{

#       bind_bw("rate_", &rate_);

#       bind("random_", &random_);

#       bind("packetSize_", &size_);

#       bind("maxpkts_", &maxpkts_);

#}


16、$cbr1 set rate_ 0.5Mb

       $cbr1 set packetSize_ 200

(1)#tcl代码:

#ns-source.tcl

#方法Application/Traffic/CBR instproc set args{}, Application/Traffic instproc set args{}

# Application/Traffic/CBR instproc set args {

#       $self instvar packetSize_ rate_

#       if { [lindex $args 0] == "interval_" } {

#                if { [llength $args] == 2 } {

#                          set ns_ [Simulator instance]

#                          set interval_ [$ns_ delay_parse [lindex $args 1]]

#                          $self set rate_ [expr $packetSize_ * 8.0/$interval_]

#                          return

#                } elseif { [llength $args] == 1 } {

#                          return [expr $packetSize_ * 8.0/$rate_]

#                }

#       }

#       eval $self next $args

#}


#Application/Traffic instproc set args {

#       $self instvar packetSize_ rate_

#       if { [lindex $args 0] == "packet_size_" } {

#                if { [llength $args] == 2 } {

#                          set packetSize_ [lindex $args 1]

#                          return

#                } elseif { [llength $args] == 1 } {

#                          return $packetSize_

#                }

#       }

## 应该还会继续调用父类方法 , 可是我找不到 Application instproc set args{}

#       eval $self next $args

#}

#

(2)#C++代码:没有


17、$cbr1 attach-agent $udp1

(1)#tcl代码:无

(2)#C++代码:

#app.cc

#通过unknown{},cmd{},command{}实现的

#int Application::command(int argc, const char*const* argv)

#{

#       …

#       else if (argc == 3) {

#                if (strcmp(argv[1], "attach-agent") == 0) {

#                          agent_ = (Agent*) TclObject::lookup(argv[2]);

#                          if (agent_ == 0) {

#                                   tcl.resultf("no such agent %s", argv[2]);

#                                   return(TCL_ERROR);

#                          }

#                          agent_->attachApp(this);

#                          return(TCL_OK);

#                }

#                …

#       }

#       return (Process::command(argc, argv));

#}

#tclcl.h

#方法TclObject::lookup(),Tcl::instance().lookup(), …, Tcl::lookup()

# inline static TclObject* lookup(const char* name) {

#                return (Tcl::instance().lookup(name));

#       }

#

#      TclObject* Tcl::lookup(const char* name)

#{

#       /*XXX use tcl hash table */

#       Tcl_HashEntry* he = Tcl_FindHashEntry(&objs_, (char*)name);

#       if (he != 0)

#                return ((TclObject*)Tcl_GetHashValue(he));

#       return (0);

#}


18、

#tcl代码:

#ns-lib.tcl

#方法Simulator instproc at args{}

# Simulator instproc at args {

#       $self instvar scheduler_

#       return [eval $scheduler_ at $args]

#}

#C++代码:没有


19、$ns_ at 5.0 "$cbr1 start"

(1)#tcl代码:无

(2)C++代码:#app.cc

#通过unknown{},cmd{},command{}实现的

# int Application::command(int argc, const char*const* argv)

#{

#       Tcl& tcl = Tcl::instance();

#

#       if (argc == 2) {

#                if (strcmp(argv[1], "start") == 0) {

#                          // enableRecv_ only if recv() exists in Tcl

#                          tcl.evalf("[%s info class] info instprocs", name_);

#                         char result[1024];

#                          sprintf(result, " %s ", tcl.result());

#                          enableRecv_ = (strstr(result, " recv ") != 0);

#                          enableResume_ = (strstr(result, " resume ") != 0);

#                          start();

#                          return (TCL_OK);

#                }

#                …

#       }

#       …

#       return (Process::command(argc, argv));

#}

#

#C++代码:app.cc

#方法start()

# void Application::start(){}

#

# void CBR_Traffic::start()

#{

#        init();

#        running_ = 1;

#        timeout();

#}


20、$ns_ at 0.0 "$node_(0) reset"

       $ns_ at 0.0 "$node_(1) reset"

(1)#tcl代码:

#ns-node.tcl

#方法reset{}, list-modules {}

#Node instproc reset {} {

#       $self instvar agents_

#       foreach a $agents_ {

#                $a reset

#       }

#       foreach m [$self list-modules] {

#                $m reset

#       }

#}

#Node instproc list-modules {} {

#       $self instvar reg_module_

#       set ret ""

#       foreach n [array names reg_module_] {

#                lappend ret $reg_module_($n)

#       }

#       return $ret

#}

(2)#C++代码有可能调用agent instproc reset;若没有,则调用class agentcommand(),不过我找了这两个地方没找到,所以我觉得有可能要看是具体哪个agent,然后调用agent的子类的#command()


21、 $ns_ at 0.6 "$node_(0) setdest 300.0 250.0 60.0"

$ns_ at 1.1 "$node_(1) setdest 300.0 300.0 60.0"

$ns_ at 40 "$node_(0) setdest 600.0 600.0 20.0"

$ns_ at 40.1 "$node_(1) setdest 100.0 100.0 20.0"

$ns_ at 50.0 "finish" 

(1)#tcl代码:无

(2)C++代码:

#mobilenode.cc,通过unknown{},cmd{},command{}实现的

#int

#MobileNode::command(int argc, const char*const* argv)

#{

#       …

#       else if (argc == 5) {

#                if (strcmp(argv[1], "setdest") == 0) {

#                          /* <mobilenode> setdest <X> <Y> <speed> */

##ifdef DEBUG

#                          fprintf(stderr, "%d - %s: calling set_destination()/n",

#                                   address_, __FUNCTION__);

##endif

#

#                          if (set_destination(atof(argv[2]), atof(argv[3]),

#                                                atof(argv[4])) < 0)

#                                   return TCL_ERROR;

#                          return TCL_OK;

#                }

#       }

#       return Node::command(argc, argv);

#}

#C++代码:

#mobilenode.cc

#方法MobileNode::set_destination()

#int

MobileNode::set_destination(double x, double y, double s)

{

         assert(initialized());

 

         if(x >= T_->upperX() || x <= T_->lowerX())

                   return -1;

         if(y >= T_->upperY() || y <= T_->lowerY())

                   return -1;

        

         update_position();   // figure out where we are now

        

         destX_ = x;

         destY_ = y;

         speed_ = s;

         …

         return 0;

}


22、$ns_ at 50.1 "puts /"NS EXITING.../"; $ns_ halt"

   proc finish {} {

         global ns_ f nf val

         $ns_ flush-trace

         close $f

         close $nf  

puts "Starting Simulation..."

(1)tcl代码:

#ns-lib.tcl

#方法Simulator instproc halt {}

#Simulator instproc halt {} {

#       $self instvar scheduler_

#       #puts "time: [clock format [clock seconds] -format %X]"

#       $scheduler_ halt

#}

(2)C++代码:

#scheduler.{h,cc}

#方法command()

# int

#Scheduler::command(int argc, const char*const* argv)

#{

#       …

#                else if (strcmp(argv[1], "halt") == 0) {

#                          halted_ = 1;

#                          return (TCL_OK);

#

#                }

#       …

#}


23、$ns_ run

#tcl, C++

#ns-lib.tcl, priqueue.cc, ns-namsupp.tcl, scheduler.cc

#方法Simulator instproc run {},这其中做了一系列初始化check-smac{}, check-node-num{}, #rtmodel-configure{}, get-routelogic{}…(若这些不在Simulator instproc中定义,那就是通过#command()在C++中定义的 );

#Node instproc reset{};

#Queue reset通过command传给PriQueue::command()来执行;然后调用了Terminate()

#Simulator instproc init-nam {}; s

#scheduler run通过command传给Scheduler::command()中定义的,然后调用了reset(); run()

# Simulator instproc run {} {

#       …

#       foreach nn [array names Node_] {

#                $Node_($nn) reset

#                …

#                }

#       }

#       …

#       foreach qn [array names link_] {

#                set q [$link_($qn) queue]

#                $q reset

#       }

#       …

#       $self init-nam

#       …

#       return [$scheduler_ run]

#}

#

#int

#PriQueue::command(int argc, const char*const* argv)

#{

#  if (argc == 2 && strcasecmp(argv[1], "reset") == 0)

#   {

#      Terminate();

#      //FALL-THROUGH to give parents a chance to reset

#    }

#  return DropTail::command(argc, argv);

#}

#

#Simulator instproc init-nam {} {

#       # 一系列初始化

#       …

#}

#

#int

#Scheduler::command(int argc, const char*const* argv)

#{

#       …

#       if (argc == 2) {

#                if (strcmp(argv[1], "run") == 0) {

#                          /* set global to 0 before calling object reset methods */

#                          reset();     // sets clock to zero

#                          run();

#                          return (TCL_OK);

#                }

#}


原创粉丝点击