分类: LINUX
2008-11-04 15:53:48
在ns中想实现到收到一个包后延迟等待收到更多的包后,统一发回复包的功能。这个问题让我郁闷了一天,想了好几种方法,才解决。为了以后少走弯路,所以这是让难能一见的技术贴在这出现的原因。
总结如下:
(一):适用NS的计时器:
建立计时器如:
1:定义一个定时器类,其中你处理超时的代码写在expire()函数里面就行了。
class Mfloodtimer : public TimerHandler {
public:
Mfloodtimer(AODV* t) : TimerHandler(), t_(t) {}
inline virtual void expire(Event*e);
protected:
AODV * t_;//你要使用定时器的那个Agent
};
2.超时执行的代码
void Myagenttimer::expire(Event *e){
cout<<"!!!!At "<
}
3.在你的协议里面怎样使用?
在AODV添加下面这个私有变量:
Myagenttimer * timer_;
这样使用
void Myagent::fuction(){
...
timer_=new Myagenttimer(this);
timer_->sched(10);
...
Function(2);
}
经过10s后面便会输出:!!!!At 10 mflood expried:(
但要注意的是程序在执行了timer_的赋值后,启动计时器,并不等计时器超时才执行timer_->sched(10)后的语句,而是启动计时器的同时就跳过这句执行后面的语句。所以要想计时器超时后才执行的函数需要放到计时器的expire函数里。
但是用计时器传递参数比较困难,虽然在expire里有参数event,但是在启动计时器的时候只能传递时间,没有其他参数传递。如果在超时时需要调用的函数需要一个非AODV成员变量类型的参数,则没有找到解决的方法。
(二)使用 sleep()函数
在linux系统中,sleep()的单位是秒,在程序头文件中加入:
#include 如上面程序将计时器替代为sleep()
void Myagent::fuction(){
...
sleep(10);
...
Function(2);
}
则程序执行到sleep,中止,等待10s后继续执行后面代码,还需要注意的是sleep使用的操作系统的时钟,跟ns里的时钟不一样,我们知道如果定义ns仿真时间10s在ns里运行时间其实并没有10s。所以要使用sleep需要注意时间之间的对应关系。好像NS还支持usleep(不确定是否这样),功能和sleep一样,对这个没有了解,有需要的查一下。还有注意的是程序在sleep时会保持节点的状态,如果节点在接收状态,则一直处于接收状态,不能再接收其他的数据包,而象我想实现的是节点在延迟的同时接收其他的数据包就不可能实现了。
(三)使用延迟事件调度机制
1:定义一个事件处理 ,其中到时时处理的代码写在handle()函数里面就行了。
class AODVTimer : public Handler {
public:
AODVTimer(AODV* a) : agent(a) {}
//inline virtual void expire (Event *);
void handle(Event *);
protected:
AODV *agent;
Event intr;
};
2.到时执行的代码
void AODVtimer::handle(Event *e){
cout<<"!!!!At "<
}
3.在你的协议里面怎样使用?
在AODV添加下面这个私有变量:
AODVtimer * timer_;
这样使用
void Myagent::fuction(){
...
Scheduler::instance().schedule(&timer, p,10);
...
Function(2);
}
这个和计时器一样,在10s后调用timer的handle函数,同时将p传递给handle函数当参数。在这里p的类型可以是packet,虽然在handle里参数类型是Event,但可以在handle函数里用强制类型再转换为packet。这样就可以访问这个packet的成员了。
最后是用第三种方法解决的,