基于NS2的AODV协议的修改与仿真的实现

最近在用ns2帮别人做移动自组网aodv协议的改进仿真实验,学习了路由仿真方面的不少知识,顺手记录下来。

ns2的安装

查阅网上资料发现ns2可以在cygwin上安装,为了省事就用cygwin安装了ns-2.35。具体的安装步骤可以参考下面的参考资料。

AODV协议的改进

ns2安装好后,所有的协议都存在ns-2.35目录下面打开aodv目录,里面就是aodv协议相关的代码了,其中aodv.cc是协议的主要代码,代码中关键的地方都有英文注释还是比较好理解的。

//收到的数据包都会先进入这个方法
void AODV::recv(Packet *p, Handler*) {
struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih = HDR_IP(p);

 assert(initialized());
 //assert(p->incoming == 0);
 // XXXXX NOTE: use of incoming flag has been depracated; In order to track direction of pkt flow, direction_ in hdr_cmn is used instead. see packet.h for details.
//如果是AODV的数据包,进入recvAODV方法
 if(ch->ptype() == PT_AODV) {
   ih->ttl_ -= 1;
   recvAODV(p);
   return;
 }


 /*
  *  Must be a packet I'm originating...
  */
if((ih->saddr() == index) && (ch->num_forwards() == 0)) {
 /*
  * Add the IP Header.  
  * TCP adds the IP header too, so to avoid setting it twice, we check if
  * this packet is not a TCP or ACK segment.
  */
  if (ch->ptype() != PT_TCP && ch->ptype() != PT_ACK) {
    ch->size() += IP_HDR_LEN;
  }
   // Added by Parag Dadhania && John Novatnack to handle broadcasting
  if ( (u_int32_t)ih->daddr() != IP_BROADCAST) {
    ih->ttl_ = NETWORK_DIAMETER;
  }
}
 /*
  *  I received a packet that I sent.  Probably
  *  a routing loop.
  */
else if(ih->saddr() == index) {
   drop(p, DROP_RTR_ROUTE_LOOP);
   return;
 }
 /*
  *  Packet I'm forwarding...
  */
 else {
 /*
  *  Check the TTL.  If it is zero, then discard.
  */
   if(--ih->ttl_ == 0) {
     drop(p, DROP_RTR_TTL);
     return;
   }
 }
// Added by Parag Dadhania && John Novatnack to handle broadcasting
 if ( (u_int32_t)ih->daddr() != IP_BROADCAST)
   rt_resolve(p);
 else
   forward((aodv_rt_entry*) 0, p, NO_DELAY);
}
//根据aodv包的类型不同,进入不同的方法
void AODV::recvAODV(Packet *p) {
 struct hdr_aodv *ah = HDR_AODV(p);

 assert(HDR_IP (p)->sport() == RT_PORT);
 assert(HDR_IP (p)->dport() == RT_PORT);

 /*
  * Incoming Packets.
  */
 switch(ah->ah_type) {

 case AODVTYPE_RREQ:
   recvRequest(p);
   break;

 case AODVTYPE_RREP:
   recvReply(p);
   break;

 case AODVTYPE_RERR:
   recvError(p);
   break;

 case AODVTYPE_HELLO:
   recvHello(p);
   break;

 default:
   fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type);
   exit(1);
 }

}

recvRequest、recvReply、recvError、recvHello对应的就是收到控制包后不同的处理方法。与之对应的send***就是发送数据包时对应的方法。

添加ns2协议

一般不建议直接修改原始的aodv协议,可以将修改的协议作为新协议添加进ns2中,具体步骤如下:

  • common/packet.h
    – 添加static const packet_t PT_XXX = XX;注意修改最后PT_NTYPE的值
    – 添加type==PT_XXX ||
    – 添加name_[PT_XXX] = 'xxx'
  • trace/cmu-trace.h
    – 添加void format_caodv(Packet *p, int offset)方法
  • trace/cmu-trace.cc
    – 对应aodv的头文件,添加新协议的头文件
    – 添加CMUTrace::format_xxx(Packet *p , int offest)函数,内容参考format_aodv函数的
    – 在void CMUTrace::format(Packet* p, const char *why)函数中参照aodv的写法添加case PT_XXX: format_xxx(p, offset); break;
  • queue/priqueue.cc
    – 在case PT_AODV下面添加case PT_XXX:
  • tcl/lib/ns-packet.tcl
    – 搜索AODV,然后在AODV的下面添加XXX,表示声明。
  • tcl/lib/ns-lib.tcl
    – 添加XXX{set ragent [$self create-xxx-agent $node]}
    – 添加
    Simulator instproc create-xxx-agent { node } {
    set ragent [new Agent/XXX[$node node-addr]]
    $self at 0.0 "$ragent start"
    $node set ragent_ $ragent
    return $ragent
    }

  • tcl/lib/ns-mobilenode.tcl
    – 为了设置协议的混杂模式,添加
    # Special processing for XXX
    set xxxonly [string first "XXX" [$agent info class]]
    if {$xxxonly != -1 } {
    $agent if-queue [$self set ifq_(0)] ;# ifq between LL and MAC
    }

协议修改好后,需要对ns2进行重新编译,cd进入ns-2.35目录,输入:make clean&&make

实验仿真

编译成功后,就要进行仿真实验了,一般采用ns-2.35/indep-utils/cmu-scen-gen/目录下的cbrgen.tcl来生成数据流,采用setdest来生成拓扑关系。具体用法如下:

ns cbrgen.tcl [ -type cbr | tcp ] [ -nn nodes ] [ -seed seed ] [-mc connections ] [ -rate rate ]

各参数定义如下:

  • -type: 数据流类型。
  • -nn:节点数目。
  • -seed: 指定随机种子。
  • -mc: 节点间的最大连接数。
  • -rate: 数据流发送速率。
./setdest -v<2> -n <nodes> -s <speed_type> -m <min_speed> -M <max_speed> -t <simulation_time> -P <pause_type> -p <pause_time> -x <max_X> -y <max_Y>

各参数定义如下:

  • -v: 指定 setdest 的版本。
  • -n: 场景中总的节点数目。
  • -p: 节点在运动到达某一目的点的暂停时间, 若设置为 0 则代表不停留。
  • -s: 节点速度分布情况, uniform 代表均匀分布, normal 代表正态分布。
  • -m: 节点移动的最小速率。
  • -M: 节点移动的最大速率。
  • -P: 节点暂停时间类型。
  • -t: 网络仿真的持续时间,单位为 s。
  • -x: 仿真区域的长度,单位: m。
  • -y: 仿真区域的宽度,单位: m。

    仿真需要写tcl文件,可以仿照aodv.tcl的例子写,如果需要开启能量模型,需要在tcl文件中配置能量节点和初始参数。
    tcl运行完后会生成“.tr”为后缀的trace文件,trace文件包含了仿真过程中的所有分组调度事件,并按时间排序,具体的trace文件格式可以参照下面的参考文献,trace文件的分析一般采用gawk来提取并统计出仿真数据,最后使用gnuplot画出图形进行对比。具体gawk的使用及各项网络性能指标的公式参看下面的参考资料。
    最后,用gnuplot把gawk分析出来的数据画出来就行了,具体方法参看参考资料。

参考资料

cygwin安装ns2.35
加入提取能量模型
trace文件分析
gawk用法介绍
gnuplot用法介绍

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值