zoukankan      html  css  js  c++  java
  • ns2节点之Classifier

    节点
      1.创建节点
      set ns [new Simulator]
      $ns node
      
      单播节点(unicast node):
      
      Tcl对象之一:地址分类器(address classifier),用来判断分组的目标地址,C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier-addr.{h/cc};
       Tcl 对象之二:端口分类器(port classifier),用来判断分组的目标Agent,C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27 /classifier/classifier-port.{ h/cc}。
      2.配置节点
      使用函数simulator::node-config{}配置即将创建的节点属性,这种节点配置方法主要针对移动节点和卫星。
      
      e.g. example2.tcl
      ——————————————————————————————————
      #设定模拟需要的一些属性,比如mobilenode的Channel、MAC、LL层的类型,天线类型,节点数目,场
      #景的长宽尺寸等。
      set val(chan) Channel/WirelessChannel ;#信道类型
      set val(prop) Propagation/TwoRayGround ;#无线-传播模型
      set val(netif) Phy/WirelessPhy ;#网络接口类型
      set val(mac) Mac/802_11 ;#MAC类型
      set val(ifq) Queue/DropTail/PriQueue ;#接口队列类型
      set val(ll) LL ;#链路层类型
      set val(ant) Antenna/OmniAntenna ;#天线模型
      set val(ifqlen) 50 ;#ifq中的最大分组
      set val(nn) 2 ;#移动节点数
      set val(rp) AODV ;#路由协议
      set val(x) 500 ;#拓扑结构的X轴范围
      set val(y) 500 ;#拓扑结构的Y轴范围
      ############################################################################################
      $set ns [new Simulator]
      ############################################################################################
       #建立节点(mobilenode)之前,先配置节点的一些参数。agentTrace表示应用层的trace,在trace文件中用#AGT表 示;routerTrace表示路由的trace,在toace文件中用RTR表示;macTrace表示MAC层的trace,
      #在trace文件中用MAC表示;movementTrace表示记录节点移动命令的trace,在trace文件中用M表示。
      $ns node-config -addressType def/ ;#设定节点地址类型:def(flat) & hierarchical
      -adhocRouting $val(rp) / ;#设定移动节点所使用的路由协议
      -llType $val(ll) / ;#设定移动节点的逻辑链路层
      -macType $val(mac) / ;#设定移动节点的MAC层
      -ifqType $val(ifq) / ;#设定移动节点的队列类型
      -ifqLen $val(ifqlen) / ;#设定移动节点的队列长度
      -antType $val(ant) / ;#设定移动节点的天线类型
      -propType $val(prop) / ;#设定移动节点的无线信号传输模型
      -phyType $val(netif) / ;#设定移动节点物理层类型
      -channelType $val(chan) / ;#设定移动节点的无线信道类型
      -topoInstance $topo / ;#设定移动节点的拓扑对象
      -agentTrace ON / ;#是否打开应用层的trace
      -routerTrace ON / ;#是否打开路由的trace
      -macTrace OFF / ;#是否打开MAC层的trace
       -movementTrace OFF ;#是否打开节点位置和移动信息的trace ############################################################################################ #建立两个节点(mobilenode),关闭节点的随机运动功能,即节点的运动完全由我们指定。
      for {set i 0} {$i < $val(nn) } {incr i} {
       set node_($i) [$ns node]
       $node_($i) random-motion 0 ;#取消随机移动
      }
      ——————————————————————————————————
      
      -addressType:设定节点地址类型:def(flat) & hierarchical。
      -adhocRouting:设定移动节点所使用的路由协议。
      -llType:设定移动节点的逻辑链路层。
      -macType:设定移动节点的MAC层。
      -ifqType:设定移动节点的队列类型。
      -ifqLen:设定移动节点的队列长度。
      -antType:设定移动节点的天线类型。
      -propType:设定移动节点的无线信号传输模型。
      -phyType:设定移动节点物理层类型。
      -channelType:设定移动节点的无线信道类型。
      -topoInstance:设定移动节点的拓扑对象。
      -wiredRouting:是否支持有限网络的路由。
      -agentTrace:是否打开应用层的trace。
      -routerTrace:是否打开路由的trace。
      -macTrace:是否打开MAC层的trace。
      -movementTrace:是否打开节点位置和移动信息的trace。
      -reset: 重置所有属性为缺省值。
      3.分类器(classifier)
      e.g. C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier.h节选
      ——————————————————————————————————
      class Classifier : public NsObject {
      public:
       Classifier();
       virtual ~Classifier();
       inline int mshift(int val) { return ((val >> shift_) & mask_); }
       virtual void recv(Packet* p, Handler* h);
      //recv()函数的实现参考源文件C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier.cc
       virtual NsObject* find(Packet*);
      // find()函数的实现参考源文件C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier.cc
       virtual int classify(Packet *);
       virtual void clear(int slot); //从表中删除对象
       virtual void install(int slot, NsObject*); //从表中增加对象
      protected:
       virtual int command(int argc, const char*const* argv);
       void alloc(int); // alloc()函数动态的分配足够的空间来放置slot
       NsObject** slot_; /* table that maps slot number to a NsObject */
       int nslot_;
       int maxslot_;
       int offset_; // offset for Packet::access()
       int shift_;
       int mask_;
       NsObject *default_target_;
       int nsize_; //what size of nslot_ should be
      };
      ——————————————————————————————————
      
      e.g. C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier.cc节选
      ——————————————————————————————————
      void Classifier::recv(Packet* p, Handler*h)
      {
       NsObject* node = find(p);
       if (node == NULL) {
       Packet::free(p);
       return;
       }
       node->recv(p,h);
      }
      
      NsObject* Classifier::find(Packet* p)
      {
       NsObject* node = NULL;
       int cl = classify(p);
       if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0) {
       if (default_target_)
       return default_target_;
       Tcl::instance().evalf("%s no-slot %ld", name(), cl);
       if (cl == TWICE) {
       cl = classify(p);
       if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0)
       return (NULL);
       }
       }
       return (node);
      }
       当classifier收到一个分组时(即recv()函数被调用时),recv()函数首先调用find()函数来处理该分组,find()函数会调 用classify()函数,不同类型的classifier对classify()函数定义不同,但各种classify函数都会对分组作检查然后返回 一个slot索引值。如果索引值有效,并指向一个有效的TclObject,recv()函数就会把分组传递给该TclObject,即调用该 TclObject的recv()函数;如果索引无效,就会清除该分组并返回。
      ——————————————————————————————————
      
      几种主要的Classifier类:
       1.address classifier按分组目的地址进行匹配,用来支持单播分组转发,通过对分组的目的地址做位运算来产生一个slot number。该类对应的classify()函数定义参考C:/cygwin/home/tchen/ns-allinone-2.27/ns- 2.27/classifier/classifier-addr.cc。
      ——————————————————————————————————
      int AddressClassifier::classify(Packet *p)
      {
       hdr_ip* iph = hdr_ip::access(p);
       return mshift(iph->daddr());
      };
       iph->daddr()函数返回分组IP头中的目的地址,mshift(int val)函数的定义在前面Classifier类的定义中可以找到,其中mask_和shift_的值可以通过Otcl来设置,缺省值分别为 0xffffffff和0,即mshift(int val)直接返回val的值。
      ——————————————————————————————————
      
       2.port classifier:按分组目的端口进行匹配,将分组传递给相应的Agent对象。该类对应的classify()函数定义参考C:/cygwin /home/tchen/ns-allinone-2.27/ns-2.27 /classifier/classifier-addr.cc。
      ——————————————————————————————————
      int PortClassifier::classify(Packet *p)
      {
       hdr_ip* iph = hdr_ip::access(p);
       return iph->dport();
      };
      iph->dport()函数返回分组IP头中的目的端口。
      ——————————————————————————————————
      
       3.replicator:与普通classifier不同,不使用classify()函数作用是生成一个分组的多份拷贝,并把这些拷贝转发给 slot表中的所有对象。在组播分组转发时,一个分组需要被转发给多个目标对象,生成分组拷贝的工作由replicator完成。Replicator类 的定义及其recv()函数的定义参考C:/cygwin/home/tchen/ns-allinone -2.27/ns-2.27/mcast/replicator.cc。
      ——————————————————————————————————
      class Replicator : public Classifier
      {
      public:
       Replicator();
       void recv(Packet*, Handler* h = 0);
       virtual int classify(Packet*) {/*NOTREACHED*/ return -1;};
      protected:
       virtual int command(int argc, const char*const* argv);
       int ignore_;
       int direction_;
      };
      
      void Replicator::recv(Packet* p, Handler*)
      {
       hdr_ip* iph = hdr_ip::access(p);
       hdr_cmn* ch = hdr_cmn::access(p);
       if (maxslot_ < 0) {
       if (!ignore_)
       Tcl::instance().evalf("%s drop %ld %ld %d", name(),
       iph->saddr(), iph->daddr(), ch->iface());
       Packet::free(p);
       return;
       }
      ……
       for (int i = 0; i < maxslot_; ++i) {
       NsObject* o = slot_[i];
       if (o != 0)
       o->recv(p->copy());
       }
       /* we know that maxslot is non-null */
       slot_[maxslot_]->recv(p);
      }
      可以看到Replicator类的recv()函数并不调用classify()函数,它只是为slot表中的每一个对象复制一份该分组的拷贝,并把拷贝发送给该对象,表中的最后一个对象收到的是原始的分组,而原始分组和拷贝实际上是完全一样的。
      ——————————————————————————————————
      
      Classifier类提供了一些Tcl实例过程,用户可以在Tcl中对Classifier对象进行控制。主要实例过程:
      1. alloc-port :寻找一个空闲的slot。
      2. clear :将号码为index的slot清空。
      3. installNext:在最后一个slot后插入一个新的指向object的表项,并返回该表项的slot号码:如果object为空,会返回错误信息。
      4. slot :产旬号码为index的slot对应对象名,如果该slot为空,会返回错误信息。
      5. findslot:查询一个object所在的slot号码,如果该object为空,会返回错误信息,如果在表中没有找到该object,会返回-1。
      6. install :将号码为index的slot所指向的对象设为object。
      
      e.g. Classifier类部分Tcl实例过程的使用方法举例,参见C:/cygwin/home/tchen/ns -allinone-2.27/mimu/example17.tcl。
      ——————————————————————————————————
      set ns [new Simulator] ;#建立一个Simulator对象的实例并把它赋值给变量ns。
      set node [$ns node] ;#新建一个节点并赋值给node。
      set udp0 [new Agent/UDP] ;#新建一个UDP Agent并赋值给udp0。
      set udp1 [new Agent/UDP] ;#新建一个UDP Agent并赋值给udp1。
      set null [new Agent/Null] ;#新建一个UDP Agent并赋值给null。
      $ns attach-agent $node $udp0; #将UDP Agent udp0绑定到node上。
      
      puts "[[$node set dmux_] slot 0]" ;#查询号码为0的slot对应的对象名并将其输出。
      puts "$udp0" ;#输出udp0的值。
      puts "[[$node set dmux_] findslot $udp0]" ;#查询udp0所在的slot号码并输出。
      puts "[[$node set dmux_] findslot $null]" ;#查询null所在的slot号码,表中没有找到该对象,返回-1,并输出。
      
      puts "============================================="
      puts "[[$node set dmux_] installNext $udp1]";#在最后一个slot 0后插入一个新的指向对象udp1的表项,返回
      ;#该表项的slot号码1,并输出。
      puts "[[$node set dmux_] slot 1]" ;#查询号码为1的slot对应的对象名并将其输出。
      puts "$udp1" ;#输出udp1的值。
      
      puts "============================================="
      [$node set dmux_] install 0 $udp1 ;#将号码为0的slot所指向的对象设为udp1。
      puts "[[$node set dmux_] slot 0]" ;#查询号码为0的slot对应的对象名并将其输出。
      
      puts "============================================="
      puts "[[$node set dmux_] alloc-port $null]" ;#寻找一个空闲的slot并输出。
      [$node set dmux_] clear 0 ;# 将号码为0的slot清空。
      puts "[[$node set dmux_] alloc-port $null]" ;#寻找一个空闲的slot并输出。
      
      puts "============================================="
      puts "[[$node set dmux_] slot 0]" ;# 查询号码为0的slot对应的对象名,该object为空,故返回错误信息。
      
      $ns run
      
      运行结果:
      
      ——————————————————————————————————
      
      相关Tcl命令:
      1. set $node [$ns node]:建立一个节点实例。
      2. $node id:返回该节点id。
      3. $node neighbors:返回邻居节点的列表。
      4. $node add-neighbor :增加一个邻居节点(注:这是单向的邻居,即“neighbor node”是node的邻居,但node不是“neighbor node”的邻居)。
      5. $node node-addr:返回节点的地址(address)。地址类型为def时,节点地址与节点id相同;地址类型为hierarchical时,节点地址是一个字符串。
      6. $node reset:重置连到这个node上的所有agent。
      7. $node agent :返回port_num端口所指向的agent对象,如果port_num端口没有指向任何对象,返回null字符串。
      8. $node attach :将agent对象连接到节点上,如果没有指定端口号,节点会自己分配一个空闲的端口,并把agent连接到该端口上;如果指定端口为port_num,节点会把agent连接到端口port_num上。
      9. $node detach :将agent与节点分离,并把一个null_agent连接到agent原来所在的端口上。
      1.创建节点
      set ns [new Simulator]
      $ns node
      
      单播节点(unicast node):
      
      Tcl对象之一:地址分类器(address classifier),用来判断分组的目标地址,C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier-addr.{h/cc};
       Tcl 对象之二:端口分类器(port classifier),用来判断分组的目标Agent,C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27 /classifier/classifier-port.{ h/cc}。
      2.配置节点
      使用函数simulator::node-config{}配置即将创建的节点属性,这种节点配置方法主要针对移动节点和卫星。
      
      e.g. example2.tcl
      ——————————————————————————————————
      #设定模拟需要的一些属性,比如mobilenode的Channel、MAC、LL层的类型,天线类型,节点数目,场
      #景的长宽尺寸等。
      set val(chan) Channel/WirelessChannel ;#信道类型
      set val(prop) Propagation/TwoRayGround ;#无线-传播模型
      set val(netif) Phy/WirelessPhy ;#网络接口类型
      set val(mac) Mac/802_11 ;#MAC类型
      set val(ifq) Queue/DropTail/PriQueue ;#接口队列类型
      set val(ll) LL ;#链路层类型
      set val(ant) Antenna/OmniAntenna ;#天线模型
      set val(ifqlen) 50 ;#ifq中的最大分组
      set val(nn) 2 ;#移动节点数
      set val(rp) AODV ;#路由协议
      set val(x) 500 ;#拓扑结构的X轴范围
      set val(y) 500 ;#拓扑结构的Y轴范围
      ############################################################################################
      $set ns [new Simulator]
      ############################################################################################
       #建立节点(mobilenode)之前,先配置节点的一些参数。agentTrace表示应用层的trace,在trace文件中用#AGT表 示;routerTrace表示路由的trace,在toace文件中用RTR表示;macTrace表示MAC层的trace,
      #在trace文件中用MAC表示;movementTrace表示记录节点移动命令的trace,在trace文件中用M表示。
      $ns node-config -addressType def/ ;#设定节点地址类型:def(flat) & hierarchical
      -adhocRouting $val(rp) / ;#设定移动节点所使用的路由协议
      -llType $val(ll) / ;#设定移动节点的逻辑链路层
      -macType $val(mac) / ;#设定移动节点的MAC层
      -ifqType $val(ifq) / ;#设定移动节点的队列类型
      -ifqLen $val(ifqlen) / ;#设定移动节点的队列长度
      -antType $val(ant) / ;#设定移动节点的天线类型
      -propType $val(prop) / ;#设定移动节点的无线信号传输模型
      -phyType $val(netif) / ;#设定移动节点物理层类型
      -channelType $val(chan) / ;#设定移动节点的无线信道类型
      -topoInstance $topo / ;#设定移动节点的拓扑对象
      -agentTrace ON / ;#是否打开应用层的trace
      -routerTrace ON / ;#是否打开路由的trace
      -macTrace OFF / ;#是否打开MAC层的trace
       -movementTrace OFF ;#是否打开节点位置和移动信息的trace ############################################################################################ #建立两个节点(mobilenode),关闭节点的随机运动功能,即节点的运动完全由我们指定。
      for {set i 0} {$i < $val(nn) } {incr i} {
       set node_($i) [$ns node]
       $node_($i) random-motion 0 ;#取消随机移动
      }
      ——————————————————————————————————
      
      -addressType:设定节点地址类型:def(flat) & hierarchical。
      -adhocRouting:设定移动节点所使用的路由协议。
      -llType:设定移动节点的逻辑链路层。
      -macType:设定移动节点的MAC层。
      -ifqType:设定移动节点的队列类型。
      -ifqLen:设定移动节点的队列长度。
      -antType:设定移动节点的天线类型。
      -propType:设定移动节点的无线信号传输模型。
      -phyType:设定移动节点物理层类型。
      -channelType:设定移动节点的无线信道类型。
      -topoInstance:设定移动节点的拓扑对象。
      -wiredRouting:是否支持有限网络的路由。
      -agentTrace:是否打开应用层的trace。
      -routerTrace:是否打开路由的trace。
      -macTrace:是否打开MAC层的trace。
      -movementTrace:是否打开节点位置和移动信息的trace。
      -reset: 重置所有属性为缺省值。
      3.分类器(classifier)
      e.g. C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier.h节选
      ——————————————————————————————————
      class Classifier : public NsObject {
      public:
       Classifier();
       virtual ~Classifier();
       inline int mshift(int val) { return ((val >> shift_) & mask_); }
       virtual void recv(Packet* p, Handler* h);
      //recv()函数的实现参考源文件C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier.cc
       virtual NsObject* find(Packet*);
      // find()函数的实现参考源文件C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier.cc
       virtual int classify(Packet *);
       virtual void clear(int slot); //从表中删除对象
       virtual void install(int slot, NsObject*); //从表中增加对象
      protected:
       virtual int command(int argc, const char*const* argv);
       void alloc(int); // alloc()函数动态的分配足够的空间来放置slot
       NsObject** slot_; /* table that maps slot number to a NsObject */
       int nslot_;
       int maxslot_;
       int offset_; // offset for Packet::access()
       int shift_;
       int mask_;
       NsObject *default_target_;
       int nsize_; //what size of nslot_ should be
      };
      ——————————————————————————————————
      
      e.g. C:/cygwin/home/tchen/ns-allinone-2.27/ns-2.27/classifier/classifier.cc节选
      ——————————————————————————————————
      void Classifier::recv(Packet* p, Handler*h)
      {
       NsObject* node = find(p);
       if (node == NULL) {
       Packet::free(p);
       return;
       }
       node->recv(p,h);
      }
      
      NsObject* Classifier::find(Packet* p)
      {
       NsObject* node = NULL;
       int cl = classify(p);
       if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0) {
       if (default_target_)
       return default_target_;
       Tcl::instance().evalf("%s no-slot %ld", name(), cl);
       if (cl == TWICE) {
       cl = classify(p);
       if (cl < 0 || cl >= nslot_ || (node = slot_[cl]) == 0)
       return (NULL);
       }
       }
       return (node);
      }
       当classifier收到一个分组时(即recv()函数被调用时),recv()函数首先调用find()函数来处理该分组,find()函数会调 用classify()函数,不同类型的classifier对classify()函数定义不同,但各种classify函数都会对分组作检查然后返回 一个slot索引值。如果索引值有效,并指向一个有效的TclObject,recv()函数就会把分组传递给该TclObject,即调用该 TclObject的recv()函数;如果索引无效,就会清除该分组并返回。
      ——————————————————————————————————
      
      几种主要的Classifier类:
       1.address classifier:按分组目的地址进行匹配,用来支持单播分组转发,通过对分组的目的地址做位运算来产生一个slot number。该类对应的classify()函数定义参考C:/cygwin/home/tchen/ns-allinone-2.27/ns- 2.27/classifier/classifier-addr.cc。
      ——————————————————————————————————
      int AddressClassifier::classify(Packet *p)
      {
       hdr_ip* iph = hdr_ip::access(p);
       return mshift(iph->daddr());
      };
       iph->daddr()函数返回分组IP头中的目的地址,mshift(int val)函数的定义在前面Classifier类的定义中可以找到,其中mask_和shift_的值可以通过Otcl来设置,缺省值分别为 0xffffffff和0,即mshift(int val)直接返回val的值。
      ——————————————————————————————————
      
       2.port classifier:按分组目的端口进行匹配,将分组传递给相应的Agent对象。该类对应的classify()函数定义参考C:/cygwin /home/tchen/ns-allinone-2.27/ns-2.27 /classifier/classifier-addr.cc。
      ——————————————————————————————————
      int PortClassifier::classify(Packet *p)
      {
       hdr_ip* iph = hdr_ip::access(p);
       return iph->dport();
      };
      iph->dport()函数返回分组IP头中的目的端口。
      ——————————————————————————————————
      
       3.replicator:与普通classifier不同,不使用classify()函数,作用是生成一个分组的多份拷贝,并把这些拷贝转发给 slot表中的所有对象。在组播分组转发时,一个分组需要被转发给多个目标对象,生成分组拷贝的工作由replicator完成。Replicator类 的定义及其recv()函数的定义参考C:/cygwin/home/tchen/ns-allinone -2.27/ns-2.27/mcast/replicator.cc。
      ——————————————————————————————————
      class Replicator : public Classifier
      {
      public:
       Replicator();
       void recv(Packet*, Handler* h = 0);
       virtual int classify(Packet*) {/*NOTREACHED*/ return -1;};
      protected:
       virtual int command(int argc, const char*const* argv);
       int ignore_;
       int direction_;
      };
      
      void Replicator::recv(Packet* p, Handler*)
      {
       hdr_ip* iph = hdr_ip::access(p);
       hdr_cmn* ch = hdr_cmn::access(p);
       if (maxslot_ < 0) {
       if (!ignore_)
       Tcl::instance().evalf("%s drop %ld %ld %d", name(),
       iph->saddr(), iph->daddr(), ch->iface());
       Packet::free(p);
       return;
       }
      ……
       for (int i = 0; i < maxslot_; ++i) {
       NsObject* o = slot_[i];
       if (o != 0)
       o->recv(p->copy());
       }
       /* we know that maxslot is non-null */
       slot_[maxslot_]->recv(p);
      }
      可以看到Replicator类的recv()函数并不调用classify()函数,它只是为slot表中的每一个对象复制一份该分组的拷贝,并把拷贝发送给该对象,表中的最后一个对象收到的是原始的分组,而原始分组和拷贝实际上是完全一样的。
      ——————————————————————————————————
      
      Classifier类提供了一些Tcl实例过程,用户可以在Tcl中对Classifier对象进行控制。主要实例过程:
      1. alloc-port :寻找一个空闲的slot。
      2. clear :将号码为index的slot清空。
      3. installNext:在最后一个slot后插入一个新的指向object的表项,并返回该表项的slot号码:如果object为空,会返回错误信息。
      4. slot :产旬号码为index的slot对应对象名,如果该slot为空,会返回错误信息。
      5. findslot:查询一个object所在的slot号码,如果该object为空,会返回错误信息,如果在表中没有找到该object,会返回-1。
      6. install :将号码为index的slot所指向的对象设为object。
      
      e.g. Classifier类部分Tcl实例过程的使用方法举例,参见C:/cygwin/home/tchen/ns -allinone-2.27/mimu/example17.tcl。
      ——————————————————————————————————
      set ns [new Simulator] ;#建立一个Simulator对象的实例并把它赋值给变量ns。
      set node [$ns node] ;#新建一个节点并赋值给node。
      set udp0 [new Agent/UDP] ;#新建一个UDP Agent并赋值给udp0。
      set udp1 [new Agent/UDP] ;#新建一个UDP Agent并赋值给udp1。
      set null [new Agent/Null] ;#新建一个UDP Agent并赋值给null。
      $ns attach-agent $node $udp0; #将UDP Agent udp0绑定到node上。
      
      puts "[[$node set dmux_] slot 0]" ;#查询号码为0的slot对应的对象名并将其输出。
      puts "$udp0" ;#输出udp0的值。
      puts "[[$node set dmux_] findslot $udp0]" ;#查询udp0所在的slot号码并输出。
      puts "[[$node set dmux_] findslot $null]" ;#查询null所在的slot号码,表中没有找到该对象,返回-1,并输出。
      
      puts "============================================="
      puts "[[$node set dmux_] installNext $udp1]";#在最后一个slot 0后插入一个新的指向对象udp1的表项,返回
      ;#该表项的slot号码1,并输出。
      puts "[[$node set dmux_] slot 1]" ;#查询号码为1的slot对应的对象名并将其输出。
      puts "$udp1" ;#输出udp1的值。
      
      puts "============================================="
      [$node set dmux_] install 0 $udp1 ;#将号码为0的slot所指向的对象设为udp1。
      puts "[[$node set dmux_] slot 0]" ;#查询号码为0的slot对应的对象名并将其输出。
      
      puts "============================================="
      puts "[[$node set dmux_] alloc-port $null]" ;#寻找一个空闲的slot并输出。
      [$node set dmux_] clear 0 ;# 将号码为0的slot清空。
      puts "[[$node set dmux_] alloc-port $null]" ;#寻找一个空闲的slot并输出。
      
      puts "============================================="
      puts "[[$node set dmux_] slot 0]" ;# 查询号码为0的slot对应的对象名,该object为空,故返回错误信息。
      
      $ns run
      
      运行结果:
      
      ——————————————————————————————————
      
      相关Tcl命令:
      1. set $node [$ns node]:建立一个节点实例。
      2. $node id:返回该节点id。
      3. $node neighbors:返回邻居节点的列表。
      4. $node add-neighbor :增加一个邻居节点(注:这是单向的邻居,即“neighbor node”是node的邻居,但node不是“neighbor node”的邻居)。
      5. $node node-addr:返回节点的地址(address)。地址类型为def时,节点地址与节点id相同;地址类型为hierarchical时,节点地址是一个字符串。
      6. $node reset:重置连到这个node上的所有agent。
      7. $node agent :返回port_num端口所指向的agent对象,如果port_num端口没有指向任何对象,返回null字符串。
      8. $node attach :将agent对象连接到节点上,如果没有指定端口号,节点会自己分配一个空闲的端口,并把agent连接到该端口上;如果指定端口为port_num,节点会把agent连接到端口port_num上。
      9. $node detach :将agent与节点分离,并把一个null_agent连接到agent原来所在的端口上。

    本文来自博客园,作者:Mr-xxx,转载请注明原文链接:https://www.cnblogs.com/MrLiuZF/p/13959316.html

  • 相关阅读:
    Beginning Auto Layout Tutorial in iOS 7: Part 2
    Beginning Auto Layout Tutorial in iOS 7: Part 1
    Autolayout 03
    Autolayout 02
    Autolayout 01
    Start Developing iOS Apps Today
    Spring 7大功能模块的作用
    struts2入门
    myeclipse导入工程 Some projects cannot be imported because they already exist in the workspace
    第十一章 Servlet MVC模式
  • 原文地址:https://www.cnblogs.com/MrLiuZF/p/13959316.html
Copyright © 2011-2022 走看看