1. 程式人生 > >基於NS2的AODV協議的修改與模擬的實現

基於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分析出來的資料畫出來就行了,具體方法參看參考資料。

參考資料