歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 對NS2中aodv源文件的淺析

對NS2中aodv源文件的淺析

日期:2017/3/1 9:43:55   编辑:Linux編程

NS裡實現的aodv是單播的,多播的aodv叫MAODV,網上有源代碼。我覺得看代碼之前最好先對協議有個了解,這樣看起來會更有效率;另外,實現與理論不一樣,如果不對代碼做改動的話,沒必要對每個細節都了解很清楚。以下將簡略介紹aodv中的重要函數。不足之處請諒解,我也是兩年前看的源代碼了,可能有些地方理解不對。

AODV中aodv.cc是最重要的,了解aodv看這個文件也就差不多了,這個文件中,起點從AODV::recv(Packet *p, Handler*) 開始,文件開頭那些都不用管。
1.Void AODV::recv(Packet *p, Handler*)
//判斷是否是aodv包,是則調用函數recvAODV(p)
if(ch->ptype() == PT_AODV) { recvAODV(p);
//本節點產生的數據包,添加IP頭
if((ih->saddr() == index) && (ch->num_forwards() == 0)) Add the IP Header
//收到本節點發送的包,說明有路由環路,丟包
else if(ih->saddr() == index) drop(p, DROP_RTR_ROUTE_LOOP);
//本節點是中間節點
else {//TTL是分組最多能轉發的次數 if(--ih->ttl_ == 0) drop(p, DROP_RTR_TTL);
//收到的不是廣播分組,解析分組
if ( (u_int32_t)ih->daddr() != IP_BROADCAST) rt_resolve(p);
//轉發 else forward((aodv_rt_entry*) 0, p, NO_DELAY);

2.void AODV::rt_resolve(Packet *p) {//解析收到的分組
//查找是否有到目的節點的路由 rt = rtable.rt_lookup(ih->daddr());
//沒有,則添加到該目的節點的路由,此時添加的路由是無效的
if(rt == 0) rt = rtable.rt_add(ih->daddr());
//有效路由,則根據路由表中信息轉發分組
if(rt->rt_flags == RTF_UP) forward(rt, p, NO_DELAY);
//如果本節點是該分組的源節點,說明沒有到目的節點的路,此時發送RREQ找路
else if(ih->saddr() == index) rqueue.enque(p); sendRequest(rt->rt_dst);
//鏈路中斷,在維護中 else if (rt->rt_flags == RTF_IN_REPAIR) rqueue.enque(p);
// 本節點轉發數據分組,但是不知道該到目的節點的路,發送RERR說明鏈路中斷
else sendError(rerr, false);

3. AODV::sendRequest(nsaddr_t dst) { //發送RREQ
//添加到目的節點的路由,此時的路由不可用,是無效的
aodv_rt_entry *rt = rtable.rt_lookup(dst);
//不到發送RREQ的時間,注意文件開頭的RREQ定時器,若沒收到RREP,源節點需要定時發送RREQ
if (rt->rt_req_timeout > CURRENT_TIME) Packet::free((Packet *)p);
//AODV中多次發送RREQ,多次發送RREQ後仍找不到路,則丟包
if (rt->rt_req_cnt > RREQ_RETRIES) rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT; drop(buf_pkt, DROP_RTR_NO_ROUTE);
//余下部分是填充路由表以及RREQ分組的內容,不涉及實現的話不用了解,了解有一定難度,需要結合整個過程看
4.void AODV::sendError(Packet *p, bool jitter) {//鏈路中斷,需要發送RERR,通知所有受影響的節點,函數體關於填充RERR內容,不用細看

5. void AODV::sendHello() {//周期發送Hello分組,以檢測鄰節點的連通性

6.void AODV::recvAODV(Packet *p) {//根據包類型調用不同函數
case AODVTYPE_RREQ recvRequest(p);
case AODVTYPE_RREP: recvReply(p);
case AODVTYPE_RERR: recvError(p);
case AODVTYPE_HELLO: recvHello(p);

7. void AODV::recvRequest(Packet *p) {//收到RREQ
// I'm the source - I recently heard this request.則丟棄該RREQ
if(rq->rq_src == index) Packet::free(p);
if (id_lookup(rq->rq_src, rq->rq_bcast_id)) Packet::free(p);
// * Cache the broadcast ID ,用於判斷是否已收到過該RREQ
id_insert(rq->rq_src, rq->rq_bcast_id);
//查找是否有到源節點的路由,有則更新,無則添加a
//* Find out whether any buffered packet can benefit from the * reverse route.緩存中是否有到源節點的數據分組,有,則建立好路由後開始發送數據
//查找是否有到目的節點的有效路由,有則向源節點回復RREP,沒有則繼續轉發該RREQ,注意轉發前需要更新RREQ中部分內容

8.void AODV::sendReply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst,
u_int32_t rpseq, u_int32_t lifetime, double timestamp) {//填充RREP內容

9. void AODV::recvReply(Packet *p) {
//查找是否有到目的節點的路由,沒有則建立,否則更新
//如果是RREP的目的節點,即RREQ的源節點則建立到目的節點的路;否則根據路由表中到源節點的路由(此路由在發送RREQ過程中已建立)轉發該RREP

10. void AODV::recvError(Packet *p) {//收到RERR,查看有哪些路徑受到中斷鏈路的影響,更新RERR內容,並向受影響的節點發送該RERR

Ubuntu 13.04 安裝NS2.35 http://www.linuxidc.com/Linux/2014-03/98266.htm

Linux平台下NS2.35安裝 http://www.linuxidc.com/Linux/2013-11/93055.htm

NS2.33在Ubuntu 12.10的完整安裝過程及相關問題 http://www.linuxidc.com/Linux/2013-05/84032.htm

NS2.33中安裝Noah協議 http://www.linuxidc.com/Linux/2012-06/63764.htm

NS2使用tcl腳本debug工具tcl-debug-2.0 http://www.linuxidc.com/Linux/2012-06/63761.htm

Copyright © Linux教程網 All Rights Reserved