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


下面以添加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文件添加到nsobject文件表中。

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 \

4tcl文件
主要的就是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

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值