ns2.35中嵌入自写协议的方法

本文介绍如何在最新版的NS2.35中嵌入一个自己写的简单新协议,读者可先不必较真协议的具体实现代码,先熟悉嵌入流程因为此代码还是有一定bug的,但实现一个协议的总体框架是对的。后续文章将对如何写一个新协议进行解析,如TCL如何传值到C++等。

一、编写新协议simple_trans

我们在 NS_HOME 根目录下创建一个文件夹 kgn,目录下有两个文件: simple_trans.h和simple_trans.cc,这两个文件就是我们新协议的主体实现文件。

 simple_trans.h代码内容

#ifndef ns_simple_trans_h
#define ns_simple_trans_h

#include "agent.h"
#include "tclcl.h"
#include "packet.h"
#include "address.h"
#include "ip.h"
//协议默认传输的端口
#define PROTOCOL_DEFAULT_PORT 1023
//同步指令(类似于 TCP 协议中三次握手的第一步,事实上我们的这个协议最终就是要实现一个简化版的三步握手)
#define PROTOCOL_INIT_SYN 1

//只有 type 这个是我定义的,其他的内容是 ns2 系统需要的
struct hdr_simple_trans {
	
	int type;
	
	static int offset_;
    inline static int& offset() {
        return offset_;
    }
    inline static hdr_simple_trans * access(const Packet * p) {
        return (hdr_simple_trans*) p->access(offset_);
    }	
};


//产生数据包、发送数据包、接收数据包的地方,包括的 target 变量就是数据包发送给的下一个目标。
class simple_trans_agent : public Agent {
	
	public :
		simple_trans_agent();
    	virtual void recv(Packet *, Handler *);//“自动”的收到网络上传输的数据包(更深层次的是经过了地址和端口过滤器)
    	void send_simple_msg(int type, int target);//创建并发送数据
    	int get_target(){ return simple_target; }//接口保护
    	
    protected:
		int simple_target;
		int simple_port;
		int command(int argc, const char*const*argv);
};

//一个定时器(闹钟)在到时时候会调用一个 expire (超时)函数
class SYNTimer : public TimerHandler {
	public:
	    SYNTimer(simple_trans_agent* t) : TimerHandler(), t_(t) {
	    }
	    inline virtual void expire(Event *);
	protected:
	    simple_trans_agent* t_;
};

#endif
simple_trans.cc代码内容

#include "simple_trans.h"
//显示系统时间
#define NOW Scheduler::instance().clock()
//得到当前节点的地址
#define MYNODE Address::instance().get_nodeaddr(addr())

int hdr_simple_trans::offset_;

static class simple_transHeaderClass : public PacketHeaderClass {
	public:
		simple_transHeaderClass() : PacketHeaderClass("PacketHeader/simple_trans",sizeof(hdr_simple_trans)) {
			bind_offset(&hdr_simple_trans::offset_);
		}
} class_simple_transhdr;

static class simple_transClass : public TclClass {
public:
	simple_transClass() : TclClass("Agent/simple_trans") {}
	TclObject* create(int, const char*const*) {
		return (new simple_trans_agent());
	}
} class_simple_trans;

simple_trans_agent::simple_trans_agent() : Agent(PT_SIMPLE_TRANS_PACKET), 
		simple_target(-1), simple_port(PROTOCOL_DEFAULT_PORT) {
	
	bind("simple_target_", &simple_target);
	bind("simple_port_", &simple_port);
	
}

//到时了就发送我们的 SYN 信息给我们的目标节点
void SYNTimer::expire(Event *){
	
	t_->send_simple_msg(PROTOCOL_INIT_SYN, t_->get_target());
	
	this->resched(1.00);
}

void simple_trans_agent::send_simple_msg(int type, int target) {
	//数据包的生成
	Packet* pkt = allocpkt();
	//数据包的访问		
	hdr_ip *iph = hdr_ip::access(pkt);
	hdr_simple_trans *shdr = hdr_simple_trans::access(pkt);
	
	if( type == PROTOCOL_INIT_SYN) {
				
		if( simple_target != -1 ) {
			iph->daddr() = simple_target;
		} else {
			printf(" no target specificed \n ");
			return ;
		}
		iph->dport() = simple_port;
		iph->saddr() = MYNODE;
		shdr->type = PROTOCOL_INIT_SYN;
		send( pkt, 0 );	
	}
}
	
int simple_trans_agent::command(int argc, const char*const* argv) {

	if( argc == 2 ) {
		if( !strcmp( argv[1], "begin" ) ) {		

			//sendsend_simple_msg( PROTOCOL_INIT_SYN, simple_target );
			SYNTimer *syn_timer = new SYNTimer(this);
			syn_timer->resched(1.00);
			
			return (TCL_OK);		
		}
	}	
					
	if( argc == 3 ) {
		
		if( !strcmp( argv[1], "set-target" ) ) {
			
			simple_target = atoi( argv[2] );
			
			printf("=>set-target = %d \n  ", simple_target);
			
			return (TCL_OK);
		}
	}		
				
	return (Agent::command(argc, argv));
}

void simple_trans_agent::recv(Packet *p, Handler *) {
	
	hdr_ip *iph = hdr_ip::access(p);	
	hdr_simple_trans *shdr = hdr_simple_trans::access(p);
	
	if( shdr->type == PROTOCOL_INIT_SYN ) {
		
		printf("=>At %lf node %d receive PROTOCOL_INIT_SYN signaling from node %d \n", 
					NOW, MYNODE, iph->saddr());
		
	} else {
		
		printf(" wrong type siganling \n");
	}
}

二、对packet.h进行修改

在 NS_HOME/common/packet.h 加入static const packet_t PT_SIMPLE_TRANS_PACKET = 74;
在 class p_info 中加入name_[PT_SIMPLE_TRANS_PACKET] = "simple_trans_packet" (非必须的)。

packet.h关键代码内容:

//add by song
static const packet_t PT_SIMPLE_TRANS_PACKET = 73;	
// insert new packet types here
static packet_t       PT_NTYPE = 74; // This MUST be the LAST one

name_[PT_NTYPE]= "undefined";
// add by song
name_[PT_SIMPLE_TRANS_PACKET] = "SIMPLE_trans_packet";

三、对ns2.35进行重新编译

最后一步,就是编译我们整个协议将其键入到 ns 中了,编译前我们要修改 makefile 文件,由于我们是在 NS_HOME/kgn 目录中所以, makefile 需要修改的有两个地方:

在 INCLUDES = 中加入 -I./kgn ,加入这个的好处就是我们在其他目录使用 simple_trans.h 的时候不用将 kgn 次级目录包含进去;

在 OBJ_CC = 中加入 kgn/simple_trans.o \ 。

makefile关键代码内容:

INCLUDES = \
	-I.  \
	-I. \
	-I/home/song/ns-allinone-2.35/tclcl-1.20 -I/home/song/ns-allinone-2.35/otcl-1.14 -I/home/song/ns-allinone-2.35/include -I/home/song/ns-allinone-2.35/include -I/home/song/ns-allinone-2.35/include -I/usr/include/pcap \
	-I./tcp -I./sctp -I./common -I./link -I./queue \
	-I./adc -I./apps -I./mac -I./mobile -I./trace \
	-I./routing -I./tools -I./classifier -I./mcast \
	-I./diffusion3/lib/main -I./diffusion3/lib \
	-I./diffusion3/lib/nr -I./diffusion3/ns \
	-I./diffusion3/filter_core -I./asim/ -I./qs \
	-I./diffserv -I./satellite \
	-I./wpan\
	-I./kgn

OBJ_CC = \
	tools/random.o tools/rng.o tools/ranvar.o common/misc.o common/timer-handler.o \
	common/scheduler.o common/object.o common/packet.o \
	common/ip.o routing/route.o common/connector.o common/ttl.o \
	trace/trace.o trace/trace-ip.o \
	classifier/classifier.o classifier/classifier-addr.o \
	classifier/classifier-hash.o \
	classifier/classifier-virtual.o \
	classifier/classifier-mcast.o \
	classifier/classifier-bst.o \
	classifier/classifier-mpath.o mcast/replicator.o \
	classifier/classifier-mac.o \
	classifier/classifier-qs.o \
	classifier/classifier-port.o src_rtg/classifier-sr.o \
        src_rtg/sragent.o src_rtg/hdr_src.o adc/ump.o \
	qs/qsagent.o qs/hdr_qs.o \
	apps/app.o apps/telnet.o tcp/tcplib-telnet.o \
	tools/trafgen.o trace/traffictrace.o tools/pareto.o \
	tools/expoo.o tools/cbr_traffic.o \
	adc/tbf.o adc/resv.o adc/sa.o tcp/saack.o \
	tools/measuremod.o adc/estimator.o adc/adc.o adc/ms-adc.o \
	adc/timewindow-est.o adc/acto-adc.o \
        adc/pointsample-est.o adc/salink.o adc/actp-adc.o \
	adc/hb-adc.o adc/expavg-est.o\
	adc/param-adc.o adc/null-estimator.o \
	adc/adaptive-receiver.o apps/vatrcvr.o adc/consrcvr.o \
	common/agent.o common/message.o apps/udp.o \
	common/session-rtp.o apps/rtp.o tcp/rtcp.o \
	common/ivs.o \
	common/messpass.o common/tp.o common/tpm.o apps/worm.o \
	tcp/tcp.o tcp/tcp-sink.o tcp/tcp-reno.o \
	tcp/tcp-newreno.o \
	tcp/tcp-vegas.o tcp/tcp-rbp.o tcp/tcp-full.o tcp/rq.o \
	baytcp/tcp-full-bay.o baytcp/ftpc.o baytcp/ftps.o \
	tcp/scoreboard.o tcp/scoreboard-rq.o tcp/tcp-sack1.o tcp/tcp-fack.o \
	tcp/scoreboard1.o tcp/tcp-linux.o tcp/linux/ns-linux-util.o \
	tcp/tcp-asym.o tcp/tcp-asym-sink.o tcp/tcp-fs.o \
	tcp/tcp-asym-fs.o \
	tcp/tcp-int.o tcp/chost.o tcp/tcp-session.o \
	tcp/nilist.o \
	sctp/sctp.o apps/sctp_app1.o\
	sctp/sctp-timestamp.o sctp/sctp-hbAfterRto.o \
	sctp/sctp-multipleFastRtx.o sctp/sctp-mfrHbAfterRto.o \
	sctp/sctp-mfrTimestamp.o \
	sctp/sctp-cmt.o \
	sctp/sctpDebug.o \
        dccp/dccp_sb.o \
        dccp/dccp_opt.o \
        dccp/dccp_ackv.o \
        dccp/dccp_packets.o \
        dccp/dccp.o \
        dccp/dccp_tcplike.o \
        dccp/dccp_tfrc.o \
	tools/integrator.o tools/queue-monitor.o \
	tools/flowmon.o tools/loss-monitor.o \
	queue/queue.o queue/drop-tail.o \
	adc/simple-intserv-sched.o queue/red.o \
	queue/semantic-packetqueue.o queue/semantic-red.o \
	tcp/ack-recons.o \
	queue/sfq.o queue/fq.o queue/drr.o queue/srr.o queue/cbq.o \
	queue/jobs.o queue/marker.o queue/demarker.o \
	link/hackloss.o queue/errmodel.o queue/fec.o\
	link/delay.o tcp/snoop.o \
	gaf/gaf.o \
	link/dynalink.o routing/rtProtoDV.o common/net-interface.o \
	mcast/ctrMcast.o mcast/mcast_ctrl.o mcast/srm.o \
	common/sessionhelper.o queue/delaymodel.o \
	mcast/srm-ssm.o mcast/srm-topo.o \
	routing/alloc-address.o routing/address.o \
	$(LIB_DIR)int.Vec.o $(LIB_DIR)int.RVec.o \
	$(LIB_DIR)dmalloc_support.o \
	webcache/http.o webcache/tcp-simple.o webcache/pagepool.o \
	webcache/inval-agent.o webcache/tcpapp.o webcache/http-aux.o \
	webcache/mcache.o webcache/webtraf.o \
	webcache/webserver.o \
	webcache/logweb.o \
	empweb/empweb.o \
	empweb/empftp.o \
	realaudio/realaudio.o \
	mac/lanRouter.o classifier/filter.o \
	common/pkt-counter.o \
	common/Decapsulator.o common/Encapsulator.o \
	common/encap.o \
	mac/channel.o mac/mac.o mac/ll.o mac/mac-802_11.o \
	mac/mac-802_11Ext.o \
	mac/mac-802_3.o mac/mac-tdma.o mac/smac.o \
	mobile/mip.o mobile/mip-reg.o mobile/gridkeeper.o \
	mobile/propagation.o mobile/tworayground.o \
	mobile/nakagami.o \
	mobile/antenna.o mobile/omni-antenna.o \
	mobile/shadowing.o mobile/shadowing-vis.o mobile/dumb-agent.o \
	common/bi-connector.o common/node.o \
	common/mobilenode.o \
	mac/arp.o mobile/god.o mobile/dem.o \
	mobile/topography.o mobile/modulation.o \
	queue/priqueue.o queue/dsr-priqueue.o \
	mac/phy.o mac/wired-phy.o mac/wireless-phy.o \
	mac/wireless-phyExt.o \
	mac/mac-timers.o trace/cmu-trace.o mac/varp.o \
	mac/mac-simple.o \
	satellite/sat-hdlc.o \
	dsdv/dsdv.o dsdv/rtable.o queue/rtqueue.o \
	routing/rttable.o \
	imep/imep.o imep/dest_queue.o imep/imep_api.o \
	imep/imep_rt.o imep/rxmit_queue.o imep/imep_timers.o \
	imep/imep_util.o imep/imep_io.o \
	tora/tora.o tora/tora_api.o tora/tora_dest.o \
	tora/tora_io.o tora/tora_logs.o tora/tora_neighbor.o \
	dsr/dsragent.o dsr/hdr_sr.o dsr/mobicache.o dsr/path.o \
	dsr/requesttable.o dsr/routecache.o dsr/add_sr.o \
	dsr/dsr_proto.o dsr/flowstruct.o dsr/linkcache.o \
	dsr/simplecache.o dsr/sr_forwarder.o \
	aodv/aodv_logs.o aodv/aodv.o \
	aodv/aodv_rtable.o aodv/aodv_rqueue.o \
	aomdv/aomdv_logs.o aomdv/aomdv.o \
	aomdv/aomdv_rtable.o aomdv/aomdv_rqueue.o \
	puma/puma.o \
	mdart/mdart_adp.o mdart/mdart_dht.o mdart/mdart_ndp.o \
	mdart/mdart_neighbor.o mdart/mdart_queue.o mdart/mdart_table.o \
	mdart/mdart.o \
	common/ns-process.o \
	satellite/satgeometry.o satellite/sathandoff.o \
	satellite/satlink.o satellite/satnode.o \
	satellite/satposition.o satellite/satroute.o \
	satellite/sattrace.o \
	rap/raplist.o rap/rap.o rap/media-app.o rap/utilities.o \
	common/fsm.o tcp/tcp-abs.o \
	diffusion/diffusion.o diffusion/diff_rate.o diffusion/diff_prob.o \
	diffusion/diff_sink.o diffusion/flooding.o diffusion/omni_mcast.o \
	diffusion/hash_table.o diffusion/routing_table.o diffusion/iflist.o \
	tcp/tfrc.o tcp/tfrc-sink.o mobile/energy-model.o apps/ping.o tcp/tcp-rfc793edu.o \
	queue/rio.o queue/semantic-rio.o tcp/tcp-sack-rh.o tcp/scoreboard-rh.o \
	plm/loss-monitor-plm.o plm/cbr-traffic-PP.o \
	linkstate/hdr-ls.o \
	mpls/classifier-addr-mpls.o mpls/ldp.o mpls/mpls-module.o \
	routing/rtmodule.o classifier/classifier-hier.o \
	routing/addr-params.o \
         nix/hdr_nv.o nix/classifier-nix.o \
         nix/nixnode.o \
         routealgo/rnode.o \
         routealgo/bfs.o \
         routealgo/rbitmap.o \
         routealgo/rlookup.o \
         routealgo/routealgo.o \
         nix/nixvec.o \
	nix/nixroute.o \
	diffserv/dsred.o diffserv/dsredq.o \
	diffserv/dsEdge.o diffserv/dsCore.o \
	diffserv/dsPolicy.o diffserv/ew.o diffserv/dewp.o \
	queue/red-pd.o queue/pi.o queue/vq.o queue/rem.o \
	queue/gk.o \
	pushback/rate-limit.o pushback/rate-limit-strategy.o \
	pushback/ident-tree.o pushback/agg-spec.o \
	pushback/logging-data-struct.o \
	pushback/rate-estimator.o \
	pushback/pushback-queue.o pushback/pushback.o \
	common/parentnode.o trace/basetrace.o \
	common/simulator.o asim/asim.o \
	common/scheduler-map.o common/splay-scheduler.o \
	linkstate/ls.o linkstate/rtProtoLS.o \
	pgm/classifier-pgm.o pgm/pgm-agent.o pgm/pgm-sender.o \
	pgm/pgm-receiver.o mcast/rcvbuf.o \
	mcast/classifier-lms.o mcast/lms-agent.o mcast/lms-receiver.o \
	mcast/lms-sender.o \
	queue/delayer.o \
	xcp/xcpq.o xcp/xcp.o xcp/xcp-end-sys.o \
	wpan/p802_15_4csmaca.o wpan/p802_15_4fail.o \
	wpan/p802_15_4hlist.o wpan/p802_15_4mac.o \
	wpan/p802_15_4nam.o wpan/p802_15_4phy.o \
	wpan/p802_15_4sscs.o wpan/p802_15_4timer.o \
	wpan/p802_15_4trace.o wpan/p802_15_4transac.o \
	apps/pbc.o \
	kgn/simple_trans.o \
	$(OBJ_STL)

如何重新编译请查看本系列中的另一篇文章NS2源码重新编译步骤。编译完成重新安装后,可以进行测试。

四、编写TCL进行测试:

# This script is created by NSG2 beta1
# <http://wushoupong.googlepages.com/nsg>

#===================================
#     Simulation parameters setup
#===================================
Antenna/OmniAntenna set Gt_ 1              ;#Transmit antenna gain
Antenna/OmniAntenna set Gr_ 1              ;#Receive antenna gain
set val(chan)   Channel/WirelessChannel    ;# channel type
set val(prop)   Propagation/TwoRayGround   ;# radio-propagation model
set val(netif)  Phy/WirelessPhy            ;# network interface type
set val(mac)    Mac/802_11                 ;# MAC type
set val(ifq)    Queue/DropTail/PriQueue    ;# interface queue type
set val(ll)     LL                         ;# link layer type
set val(ant)    Antenna/OmniAntenna        ;# antenna model
set val(ifqlen) 50                         ;# max packet in ifq
set val(nn)     2                          ;# number of mobilenodes
set val(rp)     DSDV                       ;# routing protocol
set val(x)      499                      ;# X dimension of topography
set val(y)      401                      ;# Y dimension of topography
set val(stop)   10.0                         ;# time of simulation end

#===================================
#        Initialization        
#===================================
#Create a ns simulator
set ns [new Simulator]

#Setup topography object
set topo       [new Topography]
$topo load_flatgrid $val(x) $val(y)
create-god $val(nn)

#Open the NS trace file
set tracefile [open out.tr w]
$ns trace-all $tracefile

#Open the NAM trace file
set namfile [open out.nam w]
$ns namtrace-all $namfile
$ns namtrace-all-wireless $namfile $val(x) $val(y)
set chan [new $val(chan)];#Create wireless channel

#===================================
#     Mobile node parameter setup
#===================================
$ns node-config -adhocRouting  $val(rp) \
                -llType        $val(ll) \
                -macType       $val(mac) \
                -ifqType       $val(ifq) \
                -ifqLen        $val(ifqlen) \
                -antType       $val(ant) \
                -propType      $val(prop) \
                -phyType       $val(netif) \
                -channel       $chan \
                -topoInstance  $topo \
                -agentTrace    ON \
                -routerTrace   ON \
                -macTrace      ON \
                -movementTrace ON

#===================================
#        Nodes Definition        
#===================================
#Create 2 nodes
set n0 [$ns node]
$n0 set X_ 300
$n0 set Y_ 300
$n0 set Z_ 0.0
$ns initial_node_pos $n0 20
set n1 [$ns node]
$n1 set X_ 545
$n1 set Y_ 300
$n1 set Z_ 0.0
$ns initial_node_pos $n1 20

#===================================
#        Agents Definition        
#===================================
set sT1 [new Agent/simple_trans]
#$sT1 set-target [AddrParams addr2id [$n1 node-addr]]
$sT1 set simple_target_ [AddrParams addr2id [$n1 node-addr]]
$n0 attach $sT1 1023

set sT2 [new Agent/simple_trans]
$n1 attach $sT2 1023
$sT2 set interval_ 0.1
#===================================
#        Applications Definition        
#===================================

#===================================
#        Termination        
#===================================
#Define a 'finish' procedure
proc finish {} {
    global ns tracefile namfile
    $ns flush-trace
    close $tracefile
    close $namfile
    #exec nam out.nam &
    exit 0
}
for {set i 0} {$i < $val(nn) } { incr i } {
    $ns at $val(stop) "\$n$i reset"
}
$ns at 1.0 "$sT1 begin"
$ns at $val(stop) "$ns nam-end-wireless $val(stop)"
$ns at $val(stop) "finish"
$ns at $val(stop) "puts \"done\" ; $ns halt"
$ns run

运行效果截图:

参考文献:如何在ns2中实现一个简单的网络协议》,原文基于2.31版本,本文在此基础上移植到2.35版本,进行代码修改使之适应新版并对关键代码进行注释。

原创文章,转载请注明!


  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值