NS2:添加一个新的自写协议的方法
2017-09-13 17:14
330 查看
本文介绍如何在最新版的NS-2.30中嵌入一个自己写的简单新协议,读者可先不必较真协议的具体实现代码,先熟悉嵌入流程因为此代码还是有一定bug的,但实现一个协议的总体框架是对的。后续文章将对如何写一个新协议进行解析,如TCL如何传值到C++等。
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代码内容
(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
具体截图如下:
1、
2、
在 INCLUDES = 中加入 -I./kgn ,加入这个的好处就是我们在其他目录使用 simple_trans.h 的时候不用将 kgn 次级目录包含进去;
在 OBJ_CC = 中加入 kgn/simple_trans.o \ 。
makefile关键代码内容:
具体截图如下:
1、
2、
(3)重新编译NS2源码(Terminal中完成以下步骤)。编译完成重新安装后,可以进行测试。
1、进入ns-2.30目录
2、运行make clean
3、运行make
# <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时,会报错。
运行效果截图:
一、编写新协议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
运行效果截图:
相关文章推荐
- 如何添加一个MAC协议--NS2
- 怎么在NS2中添加一个协议
- 在NS2中添加一个新的协议
- 在NS2中添加一个新的协议
- 给Android组件添加事件一个很好用的方法
- 在zencart中添加一个新页面的方法
- 如何在ns2中实现一个简单的网络协议
- Linux netlink之添加一个简单协议
- 使用泛型, 写一个为任意类型的动态数组添加元素的方法
- [ASP.NET MVC]为HtmlHelper添加一个RadioButtonList扩展方法
- UIView上添加了一个按钮和一个单击手势的事件相应,互相不影响的处理方法。。
- 添加一个js扩展方法
- 通过分类为数组添加一个倒序的一个方法. 比如: 数组中元素为 @”aa”, @”bb”, @”cc”, @”dd”, @”ee”, 倒序完之后为: @”ee”, @”dd”,@”cc”,@”bb”,@
- loadrunner一个脚本添加多台负载机器的两种方法
- JQ bind方法被选元素添加的一个或多个事件处理程序
- A视图中添加一个cell,cell继承于baseCell,baseCell上面添加一个label。点击label,让A视图中的方法响应。
- 实现一个通讯录; 通讯录可以用来存储1000个人的信息,每个人的信息包括: 姓名、性别、年龄、电话、住址 提供方法: 1. 添加联系人信息 2. 删除指定联系人信息 3. 查找指定
- 如何在ns2中实现一个简单的网络协议
- cocos2dx 添加一个新建层的方法。