NS2.35下编写协议trace文件出错原因分析

来源:互联网 发布:自学电吉他难吗 知乎 编辑:程序博客网 时间:2024/06/03 04:02

啊!!!终于成功了,经过无数次调试,编译,再调试,再编译,做为一个ns2新手,最终成功了。由于自己的粗心大意,也是因为自己对NS2机制的不熟悉导致的吧,经过1天的折磨,终于解决了。

问题:

自己模仿ping协议写了一个myping协议,为什么总是会调用到原来的ping协议?头疼。。。。。

下面贴上自己的代码,最简单,但五脏俱全:

头文件如下:

#ifndef ns_lwb2_h#define ns_lwb2_h#include "agent.h"#include "tclcl.h"#include "packet.h"#include "address.h"#include "ip.h"//define the ping packet headerstruct hdr_my_ping{char ret;double send_time;static int offset_; // required by PacketHeaderManagerinline static int& offset() { return offset_; }inline static hdr_my_ping* access(const Packet* p) {return (hdr_my_ping*) p->access(offset_);}};//define pingAgent classclass LwbAgent:public Agent{public:LwbAgent();virtualint command(int argc,const char * const * argv);virtualvoid recv(Packet *,Handler *);};#endif

.cc文件如下:
#include "lwb2.h"#include <stdio.h>int hdr_my_ping::offset_;static class MyPingHeaderClass:public PacketHeaderClass{public:MyPingHeaderClass():PacketHeaderClass("PacketHeader/myping",sizeof(hdr_my_ping)){bind_offset(&hdr_my_ping::offset_);}}class_lwbhdr;static class LwbClass:public TclClass{public :LwbClass():TclClass("Agent/lwb_pp"){}TclObject *create(int,const char*const*){return (new LwbAgent());}}class_lwb;LwbAgent::LwbAgent():Agent(PT_LWB){bind("packetSize_",&size_);printf("the my_ping packet type is %d \n",PT_LWB);}int LwbAgent::command(int argc,const char*const*argv){if(argc==2){if(strcmp(argv[1],"send")==0){printf("this is my_ping send fun ===========================\n");//create a new packetPacket *pkt=allocpkt();//access the ping header for the new packethdr_my_ping *hdr=hdr_my_ping::access(pkt);//set the 'ret'field to 0,so the receiving nodee knows that it has to generate an echo packethdr->ret=0;//store the current time in the 'send_time' fieldhdr->send_time=Scheduler::instance().clock();//send the packetsend(pkt,0);//return TCL_OK,so the calling function knows that the command has been processedreturn (TCL_OK);}}//if the command hasn't been processed by PingAgent()::command,call the command ()function for the base classreturn (Agent::command(argc,argv));}void LwbAgent::recv(Packet * pkt,Handler *){printf("this is my_ping recv=========\n");//Access the IP header for the received packet;hdr_ip *hdrip=hdr_ip::access(pkt);//Access the ping header for the received packet;    hdr_my_ping *hdr=hdr_my_ping::access(pkt);    //is the 'ret'field =0 (ie:the receiving node is being pinged?);    if(hdr->ret==0){    //send an 'echo'. First save the old packet's send_time    double stime=hdr->send_time;    //Discard the packet    Packet::free(pkt);    //Create a new packet    Packet *pktret=allocpkt();    //Access the Ping header for the new packet    hdr_my_ping *hdrret=hdr_my_ping::access(pkt);    //Set the 'ret' field to 1,so the receiver won't send another echo    hdrret->ret=1;    //Set the send_time field to the correct value    hdrret->send_time=stime;    //Send the packet    send(pktret,0);    }else{    //A packet was received. Use tcl.eval to call the Tcl    //interpreter with the ping results;    //Note: in the Tcl code,a procedure 'Agent/MyPing recv{from rtt}'    //has to be defined which allows the user to react to the ping result;    char out[100];double time=(Scheduler::instance().clock()-hdr->send_time)*1000;    //Prepare the output to the tcl interpreter.Calculate the round trip time    sprintf(out,"%s recv %d %3.1f",name(),hdrip->src_,time);    Tcl &tcl=Tcl::instance();    tcl.eval(out);    //Discard the packet    Packet::free(pkt);    }    }
看似很简单,但里面却有很多玄机:

要点1、在头文件中我们定义的包头中有一个offsed_的静态变量,我们一点要在.cc中去给他初始化,正如代码中所描述 int hdr_my_ping::offset_;

要点2、

static class MyPingHeaderClass:public PacketHeaderClass{public:MyPingHeaderClass():PacketHeaderClass("PacketHeader/myping",sizeof(hdr_my_ping)){bind_offset(&hdr_my_ping::offset_);}}class_lwbhdr;
在这段代码中我们要注意,在申明一个包头类事,我们的MyPingHeaderClass一点不能和源代码中的任何一个相同,因为这个正式OTCL与C++中进行连接的纽带类(其实是它的对象),如果相同的话可想而知(这里就不举例子了)。这个类如同下面这个:

static class LwbClass:public TclClass{public :LwbClass():TclClass("Agent/lwb_pp"){}TclObject *create(int,const char*const*){return (new LwbAgent());}}class_lwb;

同样做为纽带类,绝对不能相同,我就是因为这个问题大哭,后来自己把内容打印出来看才解决,其实大家在学习NS2源码的时候可以这样测试(虽然很笨,但很有用)。以上这个作为纽带的类对象存储在HASH表中,大家看手册的时候多认真点,就不会出现我的问题了。

其他的配置不想多说了,写这个帖子的初衷是希望所有正在被NS2虐的小伙伴能顺利解决问题,不要因为这么一个小问题而去浪费太多的时间。

如果还有什么不了解的可以给我留言,大家再讨论。

我的trace文件:

+ 0.2 0 1 myping 500 ------- 0 0.0 1.0 -1 0- 0.2 0 1 myping 500 ------- 0 0.0 1.0 -1 0r 0.214 0 1 myping 500 ------- 0 0.0 1.0 -1 0+ 0.214 1 0 myping 500 ------- 0 1.0 0.0 -1 1- 0.214 1 0 myping 500 ------- 0 1.0 0.0 -1 1r 0.228 1 0 myping 500 ------- 0 1.0 0.0 -1 1+ 0.4 1 0 myping 500 ------- 0 1.0 0.0 -1 2- 0.4 1 0 myping 500 ------- 0 1.0 0.0 -1 2r 0.414 1 0 myping 500 ------- 0 1.0 0.0 -1 2+ 0.414 0 1 myping 500 ------- 0 0.0 1.0 -1 3- 0.414 0 1 myping 500 ------- 0 0.0 1.0 -1 3r 0.428 0 1 myping 500 ------- 0 0.0 1.0 -1 3

0 0
原创粉丝点击