FunnyLeung

ns2中限制Trace文件的输出

NS2模拟的最终生成文件是一个Trace文件,其中记录了模拟中的细节。当模拟规模很大时,Trace文件也会变得相当大,甚至有十几w行,10几M大的Trace文件。一旦需要对这么大规模的实验重复进行时,模拟过程就会变得相当缓慢。一方面,程序每次要写入十几万行的数据,我们知道IO操作是较慢的。另一方面,对这么大的文件分析(如:用gawk)也需要花费较长时间。所以需要对Trace文件进行修改,尽量避免让它记录一些在分析中不必要用到的记录。

与Trace文件关联的类定义在Trace/trace.h中,源文件是trace.cc。cmu-trace.h\cmu-trace.cc,是关于无线网中trace文件的生成类。是trace的一个子类。

Trace文件记录的是每个结点的哪个层(路由层、代理层等)发送或接收包的历史记录。也就是说,每当一个结点要发送或接收到一个包时,Trace文件就会为其生成一条对应的记录。

在C++实现的Trace/cmu-trace.cc中,有一个recv函数,每当结点接收或发送包时,都会调用Trace的recv函数,为其写记录。

void CMUTrace::recv(Packet* p,Handle* h); 

从这个函数体我们可以看到下面代码是主要完成格式化一条Trace记录和写入Trace文件的过程:

format(p, "---");  //格式化
pt_->dump();   //写入缓存

 这样,我们就可以通过控制这两条语句来达到修改Trace文件的输出内容。

如:在前面两个词句前,加入以下程序段:


struct hdr_cmn* ch = HDR_CMN(p);
struct hdr_sbsw_pkt* ph;         //hdr_sbsw_pkt是自定义包

    
if(ch->ptype()==PT_SBSW){   //如果收到或发送的包是自定义的包,就可控制要不要输出这个包的记录
        ph 
= HDR_SBSW_PKT(p);
        
if(ph->pkt_type_==0){       //例如,如果自定义包中的pkt_type_值是0是,就输出,如果不是,就选择不输出
            format(p, 
"---");               //其它步骤和其它包相同
            pt_
->dump();
        }
        
if(target_ == 0)
            Packet::free(p);
        
else
            send(p, h);
        
return;
    }

 

 Trace文件的写入需要包的发送和接收触发,但是也可在程序 中控件它的发生。这时我们需要一个Trace*变量:

Trace* logtarget_; 

对这个变量的初始化,可以在command函数中。

logtarget_ = (Trace*)TclObject::lookup(argv[2]);

 这样就可以通过logtarget_在任何时候,把要写入的信息写入到Trace文件 中去。如:

sprintf(logtarget_->pt_->buffer(),"hello world");
logtarget_
->pt_->dump();    //写入缓存

 

Trace文件的写入技巧:

每向buffer()写入一次数据,就需要dump()一次。如果在dump()之前又执行了一次sprintf,那后一次会黑覆盖前一次的内容,即buffer的指针并不会自动移动。如果要实现指针移动,就要记住每次写入后的offset。

sprintf(logtarget_->pt_->buffer(),"hello world");
sprintf(logtarget_
->pt_->buffer(),"Hi");
logtarget_
->pt_->dump();
//只有"Hi","hello world"被覆盖了。

 

Code

 

 

 

 

 

 

posted on 2009-10-29 10:45  FunnyLeung  阅读(1413)  评论(0编辑  收藏  举报

导航