您的位置:首页 > 其它

【NS2】向ns中添加新的协议(ping协议)

2015-06-17 11:29 204 查看
下面以添加ping协议为例讲述如何向ns中添加协议。

1、头文件ping.h

首先定义数据结构hdr_ping,其中ret是标识符,向ping的节点发送数据包时设置为0,返回时设置为1。

send_time是时间戳,记录发送数据包时的时间,用于计算rtt。

/*
* File: Header File for a new 'Ping'Agent Class for the ns
*       network simulator
* Author: Marc Greis (greis@cs.uni-bonn.de), May 1998
*
*/
#ifndef ns_ping_h
#define ns_ping_h
#include "agent.h"
#include "tclcl.h"
#include "packet.h"
#include "address.h"
#include "ip.h"
struct hdr_ping {
char ret;
double send_time;
};
class PingAgent : public Agent {
public:
PingAgent();
int command(int argc, const char*const* argv);
void recv(Packet*, Handler*);
protected:
int off_ping_;
};
#endif


2、定义函数
/*
* File: Code for a new 'Ping' AgentClass for the ns
*       network simulator
* Author: Marc Greis (greis@cs.uni-bonn.de), May 1998
*
*/
#include "ping.h"
static class PingHeaderClass : public PacketHeaderClass {
public:
PingHeaderClass() : PacketHeaderClass("PacketHeader/Ping",
sizeof(hdr_ping)) {}
} class_pinghdr;
static class PingClass : public TclClass {
public:
PingClass() : TclClass("Agent/Ping") {}
TclObject* create(int, const char*const*) {
return (new PingAgent());
}
} class_ping;
PingAgent::PingAgent() : Agent(PT_PING)
{
bind("packetSize_", &size_);
bind("off_ping_", &off_ping_);
}
int PingAgent::command(int argc, const char*const* argv)
{
if (argc == 2) {
if (strcmp(argv[1], "send") == 0) {
// Create a new packet
Packet* pkt = allocpkt();
// Access the Ping header for the new packet:
hdr_ping* hdr =(hdr_ping*)pkt->access(off_ping_);
// Set the 'ret' field to 0, so the receivingnode 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 knowsthat 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 PingAgent::recv(Packet* pkt, Handler*)
{
// Access the IP header for the received packet:
hdr_ip* hdrip = (hdr_ip*)pkt->access(off_ip_);
// Access the Ping header for the received packet:
hdr_ping* hdr = (hdr_ping*)pkt->access(off_ping_);
// Is the 'ret' field = 0 (i.e. 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_ping* hdrret = (hdr_ping*)pktret->access(off_ping_);
// Set the 'ret' field to 1, so the receiver won't sendanother 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/Ping recv {fromrtt}'
// has to be defined which allows the user to react to theping
// result.
char out[100];
// Prepare the output to the Tcl interpreter. Calculate theround
// trip time
sprintf(out, "%s recv %d %3.1f", name(),
hdrip->src_ >> Address::instance().NodeShift_[1],
(Scheduler::instance().clock()-hdr->send_time) * 1000);
Tcl& tcl = Tcl::instance();
tcl.eval_r(out);
// Discard the packet
Packet::free(pkt);
}
}


3、对ns文件的一些改变
在packet.h中添加新的ping数据包

enum packet_t {
PT_TCP,
PT_UDP,
......
// insert new packet types here
PT_TFRC,
PT_TFRC_ACK,
PT_PING,    // packet protocol ID for our ping-agent
PT_NTYPE // This MUST be the LAST one
};


还要修改p_info()类,添加"ping"
class p_info {
public:
p_info() {
name_[PT_TCP]= "tcp";
name_[PT_UDP]= "udp";
...........
name_[PT_TFRC]="tcpFriend";
name_[PT_TFRC_ACK]="tcpFriendCtl";
name_[PT_PING]="Ping";
name_[PT_NTYPE]= "undefined";
}
.....
}


在执行make之前必须要执行make depend,否则,这两个文件可能不能被编译。
还要修改tcl/lib/ns-default.tcl文件。该文件中是TCL object的一些默认值。添加下面的代码

Agent/Ping set packetSize_ 64


在文件tcl/lib/ns-packet.tcl的头部添加下列代码

{ SRMEXT off_srm_ext_}
{ Ping off_ping_ }} {
set cl PacketHeader/[lindex $pair 0]


最后,修改Makefile文件。把ping.o文件添加到ns的object文件表中。

sessionhelper.o delaymodel.o srm-ssm.o \
srm-topo.o \
ping.o \
$(LIB_DIR)int.Vec.o $(LIB_DIR)int.RVec.o \
$(LIB_DIR)dmalloc_support.o \


4、tcl文件

主要的就是recv过程,调用c++代码中的recv()函数
Agent/Ping instproc recv {from rtt} {
$self instvar node_
puts "node [$node_ id] receivedping answer from \
$from with round-trip-time $rtt ms."
}


摘自http://endoing.spaces.live.com/blog/cns!4182DB20B664341D!181.entry?_c=BlogPart
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: