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