NS2中无线网络模拟之三(AODV路由分析)

AODV路由分析:

经过一段时间对NS2模拟器的研究,今天真正进入到了对路由算法源代码的分析过程,这里我来一步一步的来对AODV路由算法来进行分析,是自己的一段学习历程,也希望对其他正在受NS2折磨的小伙伴们带来一些帮助。下面进入正题,我们先来分析AODV的数据包的包头开始下手:

具体代码在ns-2.35/aodv/aodv_packet.h

#define AODVTYPE_HELLO  	0x01
#define AODVTYPE_RREQ   	0x02
#define AODVTYPE_RREP   	0x04
#define AODVTYPE_RERR   	0x08
#define AODVTYPE_RREP_ACK  	0x10
以上为AODV中所用到的各种数据包的包头类型的宏定义;
#define HDR_AODV(p)		((struct hdr_aodv*)hdr_aodv::access(p))
#define HDR_AODV_REQUEST(p)  	((struct hdr_aodv_request*)hdr_aodv::access(p))
#define HDR_AODV_REPLY(p)	((struct hdr_aodv_reply*)hdr_aodv::access(p))
#define HDR_AODV_ERROR(p)	((struct hdr_aodv_error*)hdr_aodv::access(p))
#define HDR_AODV_RREP_ACK(p)	((struct hdr_aodv_rrep_ack*)hdr_aodv::access(p))
获取包头对象的结构体指针,这个是基本框架;

request请求数据包格式:

struct hdr_aodv_request {
        u_int8_t        rq_type;	// Packet Type
        u_int8_t        reserved[2];
        u_int8_t        rq_hop_count;   // Hop Count
        u_int32_t       rq_bcast_id;    // Broadcast ID

        nsaddr_t        rq_dst;         // Destination IP Address
        u_int32_t       rq_dst_seqno;   // Destination Sequence Number
        nsaddr_t        rq_src;         // Source IP Address
        u_int32_t       rq_src_seqno;   // Source Sequence Number

        double          rq_timestamp;   // when REQUEST sent;
					// used to compute route discovery latency

  // This define turns on gratuitous replies- see aodv.cc for implementation contributed by
  // Anant Utgikar, 09/16/02.
  //#define RREQ_GRAT_RREP	0x80

  inline int size() { 
  int sz = 0;
  /*
  	sz = sizeof(u_int8_t)		// rq_type
	     + 2*sizeof(u_int8_t) 	// reserved
	     + sizeof(u_int8_t)		// rq_hop_count
	     + sizeof(double)		// rq_timestamp
	     + sizeof(u_int32_t)	// rq_bcast_id
	     + sizeof(nsaddr_t)		// rq_dst
	     + sizeof(u_int32_t)	// rq_dst_seqno
	     + sizeof(nsaddr_t)		// rq_src
	     + sizeof(u_int32_t);	// rq_src_seqno
  */
  	sz = 7*sizeof(u_int32_t);
  	assert (sz >= 0);
	return sz;
  }
};

路径的发现

无论何时,当源节点需要和其他节点通讯,但在其路由表内又没有相关节点的路由信息,源节点就会初始化一个路径发现进程。每个节点都会维护两个独立的计数器。一个是节点序号计数器,一个是广播ID计数器。源节点通过广播一个路由请求包RREQ到其所有邻近节点来初始化路径发现进程。RREQ包含如下域:

<source_addr; source-sequence_#; broadcast_id; dest_addr; dest_sequence_#; hop_cnt>

参数对<source_addr; broadcast_id>唯一确定了一个路由请求。当源节点发布一个新的RREQ时,broadcast_id就增值。收到RREQ的邻节点只有两种情况。情况一是该邻节点即是满足RREQ的节点,随后该节点将发送路由响应包RREP到源节点。情况二是该邻节点不是RREQ所要求的节点,则该节点将再次广播RREQ到其自己的邻节点,并对跳计数加1。需要注意的是,一个节点可能收到来自多个不同邻节点的多份相同的路由广播包的拷贝。当一个中间节点收到一个RREQ,若之前它已经收到具有相同source_addr和broadcast_id的RREQ,则抛弃多余收到的RREQ而不会重新广播多余的RREQ。若一个节点不是RREQ所要求的节点,它必须追踪部分信息以设置反向路径,这也是最终的RREP所使用的转发路径。追踪的信息包括:1.目标节点ip地址。2.源节点IP地址。3.广播ID。4.路由项目中反向路径的过期时间。5.源节点序号。

struct hdr_aodv_reply {
        u_int8_t        rp_type;        // Packet Type
        u_int8_t        reserved[2];
        u_int8_t        rp_hop_count;           // Hop Count
        nsaddr_t        rp_dst;                 // Destination IP Address
        u_int32_t       rp_dst_seqno;           // Destination Sequence Number
        nsaddr_t        rp_src;                 // Source IP Address
        double	        rp_lifetime;            // Lifetime

        double          rp_timestamp;           // when corresponding REQ sent;
						// used to compute route discovery latency
						
  inline int size() { 
  int sz = 0;
  /*
  	sz = sizeof(u_int8_t)		// rp_type
	     + 2*sizeof(u_int8_t) 	// rp_flags + reserved
	     + sizeof(u_int8_t)		// rp_hop_count
	     + sizeof(double)		// rp_timestamp
	     + sizeof(nsaddr_t)		// rp_dst
	     + sizeof(u_int32_t)	// rp_dst_seqno
	     + sizeof(nsaddr_t)		// rp_src
	     + sizeof(u_int32_t);	// rp_lifetime
  */
  	sz = 6*sizeof(u_int32_t);
  	assert (sz >= 0);
	return sz;
  }

};
一个联合体,用来设置不同的数据包头。
union hdr_all_aodv {
  hdr_aodv          ah;
  hdr_aodv_request  rreq;
  hdr_aodv_reply    rrep;
  hdr_aodv_error    rerr;
  hdr_aodv_rrep_ack rrep_ack;
};

路由表结构:

class aodv_rt_entry {
        friend class aodv_rtable;
        friend class AODV;
	friend class LocalRepairTimer;
 public:
        aodv_rt_entry();
        ~aodv_rt_entry();

        void            nb_insert(nsaddr_t id);
        AODV_Neighbor*  nb_lookup(nsaddr_t id);

        void            pc_insert(nsaddr_t id);
        AODV_Precursor* pc_lookup(nsaddr_t id);
        void 		pc_delete(nsaddr_t id);
        void 		pc_delete(void);
        bool 		pc_empty(void);

        double          rt_req_timeout;         // when I can send another req
        u_int8_t        rt_req_cnt;             // number of route requests
	
 protected:
        LIST_ENTRY(aodv_rt_entry) rt_link;

        nsaddr_t        rt_dst;    //destination address
        u_int32_t       rt_seqno;    //to reflect the referene of this add
	/* u_int8_t 	rt_interface; */
        u_int16_t       rt_hops;       		// hop count
	int 		rt_last_hop_count;	// last valid hop count
        nsaddr_t        rt_nexthop;    		// next hop IP address
	/* list of precursors */ 
        aodv_precursors rt_pclist;
        double          rt_expire;     		// when entry expires
        u_int8_t        rt_flags;      //the node status(valied,invalide,reparing)

#define RTF_DOWN 0
#define RTF_UP 1
#define RTF_IN_REPAIR 2

        /*
         *  Must receive 4 errors within 3 seconds in order to mark
         *  the route down.
        u_int8_t        rt_errors;      // error count
        double          rt_error_time;
#define MAX_RT_ERROR            4       // errors
#define MAX_RT_ERROR_TIME       3       // seconds
         */

#define MAX_HISTORY	3
	double 		rt_disc_latency[MAX_HISTORY];
	char 		hist_indx;
        int 		rt_req_last_ttl;        // last ttl value used
	// last few route discovery latencies
	// double 		rt_length [MAX_HISTORY];
	// last few route lengths

        /*
         * a list of neighbors that are using this route.
         */
        aodv_ncache          rt_nblist;
};
AODV路由协议涉及路由表管理的处理,通常在路由请求发送RREQ过程中建立反向路由,在转发RREP的时候建立正向路由,当然在数据通信的过程中也会涉及到路由表的操作,如出现了路由出错的时候以及路由生命期的更新等。
下面对AODV路由条目中的几个重要字段进行介绍:
(1)目的节点地址n_dst:用于标志使用此路由的最终目的节点,决定了数据分组转发方向。
(2)目的节点序列号rt_seqno:反映此路由的新鲜度,一般序列号越大路由越新鲜, 这是保证开环的重要措施,在路由发现和路由应答更新路由时需要进行序列号的比较。
(3)路由状态标志rt_flags(有效、无效、正在修复等):反映此路由目前的状态,主要用于告知数据分组经过此节点的时候处理方式。如果路  由处于无效状态,那么数据分组将丢失;如果处于修复状态,那么数据分组进入等待路由队列中;如果有效状态,那么直接转发。
(4)网络接口rt_interface:移动节点访问信道的接口。
(5)跳数rt_hops:到达目的节点所需要的跳数。在断链时决定是否发起本地修复时会用到,目的是控制断链修复范围;在路由更新时也会用到,目的是选择最短路径,从而降低断链几率。
(6)下一跳rt _nexthop :数据分组经过本节点之后,数据分组将被直接转发的中继节点,通常下一跳节点应该出现在当前节点的邻节点列表中。
(7)前驱节点列表rt_pclist:使用这条路由的所有直接前驱节点列表。在出现断链的时候可以通过前驱节点列表中是否存有节点而决定是否广播RERR消息。
(8)路由生命期rt_expire:路由有效的生命期,在数据分组转发使用当前路由时会更新路由的有效生命期,当较长时间不使用此路由时,此路由的有效期将会过期,在路由管理时将会使路由失效。






  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
NS2是一款常用的网络仿真工具,可以用来模拟网络各种协议的性能。AODV和DSR是两种常见的无线自组网络路由协议,它们在不同的场景下有不同的优缺点。下面是我对这两种协议的仿真分析: 1. AODV协议 AODV(Ad-hoc On-Demand Distance Vector)协议是一种基于距离向量的路由协议,它采用了按需路由的方式,即只有在需要时才去寻找路由,并且只维护已经建立的路由AODV协议每个节点都会维护一个路由表,用于存储到达目的节点的下一跳节点和距离等信息。 在NS2,我们可以通过调整一些参数来模拟AODV协议的性能,如数据传输延迟、路由发现时间、路由维护开销等。通过对这些参数进行不同的设置,我们可以得到不同的AODV协议性能指标。例如,我们可以通过比较不同节点数量下的数据传输率、平均延迟等指标来评估AODV协议的性能。 2. DSR协议 DSR(Dynamic Source Routing)协议是一种基于源路由路由协议,它不需要维护任何路由表,而是将整个路由路径存储在数据。当一个节点需要发送数据时,它会向周围节点广播一个路由请求,然后等待其他节点的响应。一旦它收到足够的响应,就可以组装出完整的路由路径,并将数据发送到目的节点。 在NS2,我们可以通过调整一些参数来模拟DSR协议的性能,如路由请求重传次数、路由维护开销等。同样地,通过对这些参数进行不同的设置,我们可以得到不同的DSR协议性能指标。例如,我们可以通过比较不同节点数量下的路由请求成功率、数据传输延迟等指标来评估DSR协议的性能。 综上所述,通过NS2的仿真分析,我们可以对AODV和DSR协议的性能进行比较和评估,从而为无线自组网络的设计和优化提供参考。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值