zoukankan      html  css  js  c++  java
  • [转]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(intconst 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(intconst 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
  • 相关阅读:
    [skill][c][ld][gcc] 明确指定gcc在链接时明确使用静态库
    [administrative][lvm] lvm 分区修改
    [administrative] windows 下制作USB启动盘的工具
    [administrative][archlinux][netctl][wpa_supplicant] 查看WIFI链接信息
    [skill][makefile] makefile 常用内容记录
    [security] security engine things
    [administrative][CentOS] 新装系统时如何正确精准的选择基础环境和软件包
    [filesystem][archlinux][disk encryption][btrfs] btrfs
    [cipher][archlinux][disk encryption][btrfs] 磁盘分区加密 + btrfs
    [administrative][archlinux][clonezilla][disk cloning] 一块 windows 10 硬盘的备份
  • 原文地址:https://www.cnblogs.com/ManMonth/p/1985518.html
Copyright © 2011-2022 走看看