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

来源:互联网 发布:淘宝一元抢拍是真的吗 编辑:程序博客网 时间:2024/05/18 02:19

NS2下AODV路由协议的数据包缓冲功能的分析与实现:


头文件为:

/*Copyright (c) 1997, 1998 Carnegie Mellon University.  All RightsReserved. Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions are met:1. Redistributions of source code must retain the above copyright notice,this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice,this list of conditions and the following disclaimer in the documentationand/or other materials provided with the distribution.3. The name of the author may not be used to endorse or promote productsderived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIESOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OROTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IFADVISED OF THE POSSIBILITY OF SUCH DAMAGE.The AODV code developed by the CMU/MONARCH group was optimized and tuned by Samir Das and Mahesh Marina, University of Cincinnati. The work was partially done in Sun Microsystems. */#ifndef __aodv_rqueue_h__#define __aodv_rqueue_h_//#include <packet.h>#include <ip.h>#include <agent.h>/* * The maximum number of packets that we allow a routing protocol to buffer. */#define AODV_RTQ_MAX_LEN     64      // packets/* *  The maximum period of time that a routing protocol is allowed to buffer *  a packet for. */#define AODV_RTQ_TIMEOUT     30// secondsclass aodv_rqueue : public Connector { public:        aodv_rqueue();        void            recv(Packet *, Handler*) { abort(); }        void            enque(Packet *p);inline int      command(int argc, const char * const* argv)   { return Connector::command(argc, argv); }        /*         *  Returns a packet from the head of the queue.         */        Packet*         deque(void);        /*         * Returns a packet for destination "D".         */        Packet*         deque(nsaddr_t dst);  /*   * Finds whether a packet with destination dst exists in the queue   */        char            find(nsaddr_t dst); private:        Packet*         remove_head();        void            purge(void);voidfindPacketWithDst(nsaddr_t dst, Packet*& p, Packet*& prev);bool findAgedPacket(Packet*& p, Packet*& prev); voidverifyQueue(void);        Packet          *head_;        Packet          *tail_;        int             len_;        int             limit_;        double          timeout_;};#endif /* __aodv_rqueue_h__ */

随着AODV的源代码来到了缓存实现这块,根据头文件可以知道,aodv_rqueue是继承了Connector,既然是一个队列,为什么不去实现一个队列,而是去继承Connector?

那么Connector在这里起到了什么作用?从头文件中可以看到,在我们熟悉的2个函数中

     void            recv(Packet *, Handler*) { abort(); }        void            enque(Packet *p);inline int      command(int argc, const char * const* argv)   { return Connector::command(argc, argv); }

recv 和command已经被实现了,而且在recv中调用了abort()函数。这是为什么?根据abort()函数的功能是终止程序的运行。这里难道不用recv()函数吗?查看connector类文档:

Connectors, unlink classifiers, only generate data for one recipient; either the packet is delivered to the target_ neighbor,
or it is sent to he drop-target_.

A connector will receive a packet, perform some function, and deliver the packet to its neighbor, or drop the packet. There
are a number of different types of connectors in ns. Each connector performs a different function.
Connector就这么简单,如果有邻居对象,就递交,否则丢弃。确实看不出来什么。
/*Copyright (c) 1997, 1998 Carnegie Mellon University.  All RightsReserved. Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions are met:1. Redistributions of source code must retain the above copyright notice,this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice,this list of conditions and the following disclaimer in the documentationand/or other materials provided with the distribution.3. The name of the author may not be used to endorse or promote productsderived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIESOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OROTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IFADVISED OF THE POSSIBILITY OF SUCH DAMAGE.The AODV code developed by the CMU/MONARCH group was optimized and tuned by Samir Das and Mahesh Marina, University of Cincinnati. The work was partially done in Sun Microsystems.*/#include <assert.h>#include <cmu-trace.h>#include <aodv/aodv_rqueue.h>#define CURRENT_TIME    Scheduler::instance().clock()#define QDEBUG/*  Packet Queue used by AODV.*/aodv_rqueue::aodv_rqueue() {  head_ = tail_ = 0;  len_ = 0;  limit_ = AODV_RTQ_MAX_LEN;  timeout_ = AODV_RTQ_TIMEOUT;}voidaodv_rqueue::enque(Packet *p) {struct hdr_cmn *ch = HDR_CMN(p); /*  * Purge any packets that have timed out.  */ purge();  p->next_ = 0; ch->ts_ = CURRENT_TIME + timeout_; if (len_ == limit_) { Packet *p0 = remove_head();// decrements len_   assert(p0);   if(HDR_CMN(p0)->ts_ > CURRENT_TIME) {     drop(p0, DROP_RTR_QFULL);   //drop because this queue is  full;   }   else {     drop(p0, DROP_RTR_QTIMEOUT);   //drop because this packet is timeout   } }  /**  * to implement the queue;and tail insert;  */ if(head_ == 0) {   head_ = tail_ = p; } else {   tail_->next_ = p;   tail_ = p; } len_++;#ifdef QDEBUG   verifyQueue();#endif // QDEBUG}                Packet*aodv_rqueue::deque() {Packet *p; /*  * Purge any packets that have timed out.  */ purge(); p = remove_head();#ifdef QDEBUG verifyQueue();#endif // QDEBUG return p;}Packet*aodv_rqueue::deque(nsaddr_t dst) {Packet *p, *prev; /*  * Purge any packets that have timed out.  */ purge(); findPacketWithDst(dst, p, prev); assert(p == 0 || (p == head_ && prev == 0) || (prev->next_ == p)); if(p == 0) return 0; if (p == head_) {   p = remove_head(); } else if (p == tail_) {   prev->next_ = 0;   tail_ = prev;   len_--; } else {   prev->next_ = p->next_;   len_--; }#ifdef QDEBUG verifyQueue();#endif // QDEBUG return p;}char aodv_rqueue::find(nsaddr_t dst) {Packet *p, *prev;   findPacketWithDst(dst, p, prev); if (0 == p)   return 0; else   return 1;}/*  Private Routines*/Packet*aodv_rqueue::remove_head() {Packet *p = head_;         if(head_ == tail_) {   head_ = tail_ = 0; } else {   head_ = head_->next_; } if(p) len_--; return p;}voidaodv_rqueue::findPacketWithDst(nsaddr_t dst, Packet*& p, Packet*& prev) {    p = prev = 0;  for(p = head_; p; p = p->next_) {  //if(HDR_IP(p)->dst() == dst) {       if(HDR_IP(p)->daddr() == dst) {      return;    }    prev = p;  }}voidaodv_rqueue::verifyQueue() {Packet *p, *prev = 0;int cnt = 0; for(p = head_; p; p = p->next_) {   cnt++;   prev = p; } assert(cnt == len_); assert(prev == tail_);}/*voidaodv_rqueue::purge() {Packet *p; while((p = head_) && HDR_CMN(p)->ts_ < CURRENT_TIME) {   // assert(p == remove_head());        p = remove_head();        drop(p, DROP_RTR_QTIMEOUT); }}*//** * parameter p,prev pointer * to find a timeout packet; */boolaodv_rqueue::findAgedPacket(Packet*& p, Packet*& prev) {    p = prev = 0;  for(p = head_; p; p = p->next_) {    if(HDR_CMN(p)->ts_ < CURRENT_TIME) {      return true;    }    prev = p;  }  return false;}voidaodv_rqueue::purge() {Packet *p, *prev; while ( findAgedPacket(p, prev) ) { assert(p == 0 || (p == head_ && prev == 0) || (prev->next_ == p)); if(p == 0) return; if (p == head_) {   p = remove_head(); } else if (p == tail_) {   prev->next_ = 0;   tail_ = prev;   len_--; } else {   prev->next_ = p->next_;   len_--; }#ifdef QDEBUG verifyQueue();#endif // QDEBUGp = prev = 0; //initial the p and prev; }}
查看实现文件,发现里面根本没有用到网络部分的知识,其实这就是一个FIFO的队列C++版本实现。自己定义了
Packet * head_
Packet *tail_
这2个指针,这就是说这个对列是在这里实现的,而不是下层的网络接口层队列。这个队列是在AODV的缓存区中实现的。仅仅把它当做一个队列即可(包的队列)。
继承Connector还没有发现它的用处,等发现了再记下来。现在就认为它是一个队列来使用。


0 0
原创粉丝点击