使用ns2仿真ping

费了好大劲,终于按照ns-2官网的tutorial( http://www.isi.edu/nsnam/ns/tutorial/nsnew.html 完成了第一个简单的demo:ping程序的仿真, 感觉有必要记录下实现的过程, 因为感觉tutorial并不尽善尽美。
1、下载、安装的ns-2. 34版已经内置了ping程序的相关数据结构的定义, 而tutorial中使用的包括hdr_ping(包头), PingAgent(ping代理), PingHeaderClass(ping头类), PingClass(Ping类)在相关文件中已经有定义了。 因此在进行编程时需要使用自定义的名称, 我采取的方法是在前面加了个my前缀;
2、Turorial中关于修改ns2.34/tcl/lib/ ns-packet.tcl的说明有问题,原文是:

        { SRMEXT off_srm_ext_}
        { Ping off_ping_ }} {
set cl PacketHeader/[lindex $pair 0]
 原文的意识应该是在第一行和第三行之间加上{Ping off_ping_},整体应该是在一个大的循环中, 但是在本版本中并没有找到相关的代码,但是找到了另一段,即

#foreach pair {
#        {      LDP off_ldp_        }
          {      Myping off_ping_  }
# }{
#       create-packet-header [lindex $pair 0] [lindex $pair 1]
}

将该foreach和create-packet-header的注解去掉,然后向其中加入元组{Myping off_ping_}。

其他的操作步骤按照tutorial来做基本就可以了。

将添加myping协议的整体步骤总结如下:

一、编写c++程序

(1)在ns2.34目录下创建villasy子目录,用来存放自己编写的代码,在该目录下创建myping.h、myping.cc和myping.tcl等。

myping.h:对ping包头结构体定义hdr_myping、对Ping代理进行定义MyPingAgent;

myping.cc:定义ping头类MyPingHeaderClass,定义Ping类MyPingClass,实现MyPingAgent中的command、recv函数;

(2)对C++程序与OTcl程序互访问的原理;

二、修改ns-2相关配置

(1)ns2.34/common/packet.h,增加该程序所使用的包的定义,低版本用的是enum packet,在本2.34版本中,使用的是static const int方法,找到定义的块,增加static const packet_t PT_MYPING = 62,将PT_NTYPE加1成63;tutorial中直接修改p_info()构造函数,但本版中构造函数调用了initName函数,因此修改该函数,添加name_[PT_MYPING] = "Myping";

(2)ns2.34/tcl/lib/ns-packet.h中前文论述tutorial不足中所说修改,创建此种类型的数据包;ns2.34/tcl/lib/ns-default.h添加Agent/Myping set packetSize_ 64,设置包的大小;

三、修改ns2.34下Makefile文件

为了编译修改过的结果,在Makefile中找到链接.o文件的块,添加villasy/myping.o ,按照tutorial在ns2.34下首先make depend,报错,于是直接make,编译通过;

四、编写myping.tcl文件,该文件用来设定场景

如tutorial所述

最后,ns villasy/myping.tcl,得到结果,如附件中截图。

myping.h

/*
 * 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_myping {
  char ret;
  double send_time;
  //header access methods;
  static int offset_;
  inline static hdr_myping* access(const Packet* p){
    return (hdr_myping*)p->access(offset_);
  }
};


class MyPingAgent : public Agent {
    public:
        MyPingAgent();
        int command(int argc, const char*const* argv);
        void recv(Packet*, Handler*);
    protected:
        int off_ping_;
        int packetSize_;
        //int off_ip_;
};


#endif

myping.cc

#include "myping.h"

static class MyPingHeaderClass : public PacketHeaderClass{
    public:
        MyPingHeaderClass() : PacketHeaderClass("PacketHeader/Myping",sizeof(hdr_myping)){}
}class_mypinghdr;

static class MyPingClass : public TclClass{
    public:
        MyPingClass() : TclClass("Agent/Myping"){}
        TclObject* create(int ,const char*const*){
            return (new MyPingAgent());
        }
}class_myping;

//PingAgent constructor
MyPingAgent::MyPingAgent() : Agent(PT_MYPING){
    bind("packetSize_",&size_);
    //bind("off_ping_",&off_ping_);
    //bind("off_ip_",&off_ip_);
}

int MyPingAgent::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 header
            hdr_myping *hdr = (hdr_myping*)pkt->access(off_ping_);
            //set the 'ret' field to 0,so the receiving node knows
            //that it has to generate an echo packet
            hdr->ret = 0;
            //store the current time in '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 has not been processed by PingAgent()::command,
    //call the command() function for the base class
    return (Agent::command(argc,argv));
}

void MyPingAgent::recv(Packet* pkt, Handler*){
    //acess the Ping header for the received packet
    hdr_myping* hdr = (hdr_myping*)pkt->access(off_ping_);
    //access the ip header for the received packet
    hdr_ip* hdrip = (hdr_ip*)pkt->access(off_ip_);
    //is the 'ret' field = 0(the receiving node is being pinged)
    if(hdr->ret ==0){
        //send an 'echo'. 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();
        //acess the Ping header for the new packet
        hdr_myping* hdrret = (hdr_myping*)pktret->access(off_ping_);
        //set the 'ret' field to 1,so the receiver won't send anothe
        hdrret->ret = 1;
        //set the send_time field to the correct value
        hdrret->send_time = stime;
        send(pktret,0);
    }else{
        //use tcl.eval to call the Tcl interpreter
        char out[100];
        sprintf(out,"%s recv %d %3.1f", name(), hdrip->src_.addr_ >> Address::instance().NodeShift_[1],(Scheduler::instance().clock()-hdr->send_time)*1000);
        Tcl& tcl = Tcl::instance();
        tcl.eval(out);
        //discard the packet
        Packet::free(pkt);
    }
}

#Create a simulator object
set ns [new Simulator]

#Open a trace file
set nf [open out.nam w]
$ns namtrace-all $nf

#Define a 'finish' procedure
proc finish {} {
        global ns nf
        $ns flush-trace
        close $nf
        exec nam out.nam &
        exit 0
}

#Create three nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]

#Connect the nodes with two links
$ns duplex-link $n0 $n1 1Mb 10ms DropTail
$ns duplex-link $n1 $n2 1Mb 10ms DropTail

#Define a 'recv' function for the class 'Agent/Ping'
Agent/Myping instproc recv {from rtt} {
	$self instvar node_
	puts "node [$node_ id] received ping answer from \
              $from with round-trip-time $rtt ms."
}

#Create two ping agents and attach them to the nodes n0 and n2
set p0 [new Agent/Myping]
$ns attach-agent $n0 $p0

set p1 [new Agent/Myping]
$ns attach-agent $n2 $p1

#Connect the two agents
$ns connect $p0 $p1

#Schedule events
$ns at 0.2 "$p0 send"
$ns at 0.4 "$p1 send"
$ns at 0.6 "$p0 send"
$ns at 0.6 "$p1 send"
$ns at 1.0 "finish"

#Run the simulation
$ns run



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值