您的位置:首页 > 其它

NS2:添加一个新的自写协议的方法

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

一、编写新协议simple_trans

我们在 NS-2.30目录下创建一个文件夹 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-2.30/common/packet.h :

(1)在enum packet_t中的最后加入 PT_SIMPLE_TRANS_PACKET,  (注意后面的逗号不能省略)
(2)在 class p_info 中最后加入name_[PT_SIMPLE_TRANS_PACKET] = "simple_trans_packet" ; (注意后面的分号不能省略)。

packet.h关键代码内容:

//add by song
PT_SIMPLE_TRANS_PACKET
// insert new packet types here
PT_NTYPE // This MUST be the LAST one
name_[PT_SIMPLE_TRANS_PACKET] = "SIMPLE_trans_packet";
name_[PT_NTYPE]= "undefined";

具体截图如下:

1、

 


2、



三、对ns-2.30进行重新编译

最后一步,就是编译我们整个协议将其键入到 ns 中了,编译前我们要修改 makefile 文件(root权限下修改才能保存),由于我们是在ns-2.30/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 \
......
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)


具体截图如下:
1、



2、



(3)重新编译NS2源码(Terminal中完成以下步骤)。编译完成重新安装后,可以进行测试。
1、进入ns-2.30目录
2、运行make clean
3、运行make

四、编写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

注意:TCL脚本文件中的节点配置语句中,符号“\”后面不能有空格,
否则在执行ns simple_trans.tcl时,会报错。
$ns node-config -adhocRouting  $val(rp) \
-llType        $val(ll) \
-macType       $val(mac) \
......
-channel       $chan \
-topoInstance  $topo \
-agentTrace    ON \
-routerTrace   ON \
-macTrace      ON \
-movementTrace ON


运行效果截图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  NS2 添加新协议