ns2中的队列,Packet

ns2中收发的数据包一般都需要排队,也就是说数据包需要组成一个FIFO的队列。队列的形成与Packet类有关。

Packet类在/ns-allinone-2.35/ns-2.35/common/packet.h中定义(HDR_CMN在同一个文件中定义)。

class Packet : public Event {
private:
	unsigned char* bits_;	// header bits
//	unsigned char* data_;	// variable size buffer for 'data'
//  	unsigned int datalen_;	// length of variable size buffer
	AppData* data_;		// variable size buffer for 'data'
	static void init(Packet*);     // initialize pkt hdr 
	bool fflag_;
protected:
	static Packet* free_;	// packet free list
	int	ref_count_;	// free the pkt until count to 0
public:
	Packet* next_;		// for queues and the free list
	static int hdrlen_;

	Packet() : bits_(0), data_(0), ref_count_(0), next_(0) { }
	inline unsigned char* bits() { return (bits_); }
	inline Packet* copy() const;
	inline Packet* refcopy() { ++ref_count_; return this; }
	inline int& ref_count() { return (ref_count_); }
	static inline Packet* alloc();
	static inline Packet* alloc(int);
	inline void allocdata(int);
	// dirty hack for diffusion data
	inline void initdata() { data_  = 0;}
	static inline void free(Packet*);
	inline unsigned char* access(int off) const {
		if (off < 0)
			abort();
		return (&bits_[off]);
	}
	// This is used for backward compatibility, i.e., assuming user data
	// is PacketData and return its pointer.
	inline unsigned char* accessdata() const { 
		if (data_ == 0)
			return 0;
		assert(data_->type() == PACKET_DATA);
		return (((PacketData*)data_)->data()); 
	}
	// This is used to access application-specific data, not limited 
	// to PacketData.
	inline AppData* userdata() const {
		return data_;
	}
	inline void setdata(AppData* d) { 
		if (data_ != NULL)
			delete data_;
		data_ = d; 
	}
	inline int datalen() const { return data_ ? data_->size() : 0; }

	// Monarch extn

	static void dump_header(Packet *p, int offset, int length);

	// the pkt stamp carries all info about how/where the pkt
        // was sent needed for a receiver to determine if it correctly
        // receives the pkt
        PacketStamp	txinfo_;  

	/*
         * According to cmu code:
	 * This flag is set by the MAC layer on an incoming packet
         * and is cleared by the link layer.  It is an ugly hack, but
         * there's really no other way because NS always calls
         * the recv() function of an object.
	 * 
         */
        u_int8_t        incoming;

	//monarch extns end;
};

Packet的构造函数如下:

Packet() : bits_(0), data_(0), ref_count_(0), next_(0) { }

初始化列表分别包括了指向数据包头部的指针bits_,指向数据的指针data_,数据包长度ref_count以及指向队列下一个元素的指针next_。


在实现以Packet为元素的队列时,只需要添加两个指针,分别指向队列的头部和尾部即可。

以AOMDV协议中的队列为例:

class aomdv_rqueue : public Connector {
 public:
        aomdv_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);
	void		findPacketWithDst(nsaddr_t dst, Packet*& p, Packet*& prev);
	bool 		findAgedPacket(Packet*& p, Packet*& prev); 
	void		verifyQueue(void);

        Packet          *head_;
        Packet          *tail_;

        int             len_;

        int             limit_;
        double          timeout_;

};
之后通过操作*head_和*tail_就可以对队列进行入队,出队,查找等操作了。

你可能感兴趣的:(ns2中的队列,Packet)