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

啊!!!终于成功了,经过无数次调试,编译,再调试,再编译,做为一个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 header
struct hdr_my_ping{
	char ret;
	double send_time;
	static int offset_; // required by PacketHeaderManager
	inline static int& offset() { return offset_; }
	inline static hdr_my_ping* access(const Packet* p) {
		return (hdr_my_ping*) p->access(offset_);
	}


};


//define pingAgent class
class LwbAgent:public Agent{
public:
	LwbAgent();
virtual	int command(int argc,const char * const * argv);
virtual	void 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 packet
			Packet *pkt=allocpkt();
			//access the ping header for the new packet
			hdr_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 packet
			hdr->ret=0;
			//store the current time in the 'send_time' field
			hdr->send_time=Scheduler::instance().clock();
			//send the packet
			send(pkt,0);
			//return TCL_OK,so the calling function knows that the command has been processed
			return (TCL_OK);
		}
	}
	//if the command hasn't been processed by PingAgent()::command,call the command ()function for the base class

	return (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 0
r 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 1
r 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 2
r 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 3
r 0.428 0 1 myping 500 ------- 0 0.0 1.0 -1 3

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值