ns2仿真学习(六)-自定义协议

这次,我是仿照ns2中的sctp,实现了一个多宿主的UDP协议,目前还比较简单,只能获取端到端的rtt,能够明显看到数据包的乱序情况。中间遇到遇到一些小波折,记录在此,以备后用。

在ns2目录下增加文件夹mpudpns2,放置所有的源文件。

调试的log,采用的是[1],放在mpudpns2文件下即可使用。当然这个log程序是C语言的,用在C++的环境中需要在h文件中,增加一个宏定义

#ifdef __cplusplus
extern "C" {
#endif

#复制原有的内容

#ifdef __cplusplus
}
#endif
定义协议头文件mpudphdr.h,里面定义个两种数据包类型,hdr_mpudp和hdr_mpudp_ack。定义如下:

struct hdr_mpudp
{
	double timestamp;
	int flowid;
	int packetid;
    // Packet header access functions
    static int offset_;
    inline static int &offset() {
	return offset_;
    }

    inline static hdr_mpudp*access(const Packet * p) {
		return (hdr_mpudp *) p->access(offset_);
	}
};
struct hdr_mpudp_ack
{
	double timestamp;
	double mpudp_timestamp;//is the timestamp in hdr_mpudp;
	int packetid;
	int flow_id_;
    // Packet header access functions
    static int offset_;
    inline static int &offset() {
	return offset_;
    }

    inline static hdr_mpudp_ack*access(const Packet * p) {
		return (hdr_mpudp_ack *) p->access(offset_);
	}
};
在mpudp.cc文件内定义类注册相应的数据包头偏移,就是Packet中的结构体中的bits_会携带自定义协议头的空间,之后可以通过类型转换,将bits_中的内存进行强制转换,获取自定义的报文头,(hdr_mpudp *) p->access(offset_)。注册报文头偏移的类如下:

static class MpUdpHeaderClass:public PacketHeaderClass
{
public:
	MpUdpHeaderClass():PacketHeaderClass("PacketHeader/MpUdp",sizeof(hdr_mpudp)){
		bind_offset(&hdr_mpudp::offset_);
	}
}class_mpudp_header;
static class MpUdpAckHeaderClass:public PacketHeaderClass
{
public:
	MpUdpAckHeaderClass():PacketHeaderClass("PacketHeader/MpUdpAck",sizeof(hdr_mpudp_ack))
	{
		bind_offset(&hdr_mpudp_ack::offset_);
	}
}class_mpudpack_header;
这个时候,需要在ns-packet.tcl(在ns2.35/tcl/lib/文件夹下)脚本中写入相应报文头的名字,名字与PacketHeader/MpUdp中的第二项保持一致。如果不增加这一项,根本不能在Packet中访问自定义的数据报头。

# Application-Layer Protocols:
	Message # a protocol to carry text messages
	Ping 	# Ping
    	PBC     # PBC
	MpUdp
	MpUdpAck

在ns-lib.tcl中仿照SCTP的处理方式,增加相应的命令处理,修改了两处:

//ns-lib.tcl?line=1516
Simulator instproc attach-agent { node agent }
	if {[lindex [split [$agent info class] "/"] 1] == "MpUdpAgent"} {
		$agent instvar multihome_bindings_
		set binding_ {}
		set addr [$agent set agent_addr_]
		set port [$agent set agent_port_]
		lappend binding_ $addr
		lappend binding_ $port
		lappend multihome_bindings_ $binding_
	}

	
//ns-lib.tcl  
Simulator instproc connect {src dst}
    	if {[lindex [split [$src info class] "/"] 1] == "MpUdpAgent"} {
    		$self multihome-connect $src $dst
    	}

另外,需要定义数据包类型和相应的名称

        // insert new packet types here
static const packet_t PT_MPUDP=73; //[zsy-2017]
static const packet_t PT_MPUDP_ACK=74;//[zsy-2017]
static packet_t       PT_NTYPE = 75; // This MUST be the LAST one

name_[PT_MPUDP]="MPUDP";
name_[PT_MPUDP_ACK]="MPUDP_ACK";

在Makefile.in中增加需要编译的源文件:

mpudpns2/log.o  mpudpns2/mpudp.o\

之后在ns-2.35文件下执行./configure 生成makefile,执行make,编译

最后的仿真脚本mpudp.tcl

	set ns [new Simulator]

	set host0_core [$ns node]
	set host0_if0 [$ns node]
	set host0_if1 [$ns node]

	$host0_core color Red
	$host0_if0 color Red
	$host0_if1 color Red

	$ns multihome-add-interface $host0_core $host0_if0
	$ns multihome-add-interface $host0_core $host0_if1

    set host1_core [$ns node]
    set host1_if0 [$ns node]
    set host1_if1 [$ns node]
    $host1_core color Blue
	$ns multihome-add-interface $host1_core $host1_if0
	$ns multihome-add-interface $host1_core $host1_if1    
    set router [$ns node]
    
    $ns duplex-link $host0_if0 $router 1Mb 200ms DropTail
    $ns duplex-link $host0_if1 $router 1Mb 100ms DropTail
    
    $ns duplex-link $host1_if0 $router 2Mb 200ms DropTail
    $ns duplex-link $host1_if1 $router 2Mb 100ms DropTail
	
	set mpudp0  [new Agent/MpUdpAgent]
	
	$ns multihome-attach-agent $host0_core $mpudp0
	$mpudp0 sender_trace "mpudpsender.txt"
	
	set mpudp1 [new Agent/MpUdpAgent]
	$mpudp1 receiver_trace "mpudpreceiver.txt"
	$ns multihome-attach-agent $host1_core $mpudp1
	
	$ns connect $mpudp0 $mpudp1
    set cbr0 [new Application/Traffic/CBR]
	$cbr0 set type_ CBR  
	$cbr0 set packet_size_ 1000  
	$cbr0 set rate_ 1mb  
	$cbr0 set random_ false 
    $cbr0 attach-agent $mpudp0	

	$ns at 0.1 "$cbr0 start"
	$ns at 5.0 "$cbr0 stop"
	
	$ns run 

最后的代码下载[2].

接收端接收到的ack之后答应的日志,可以明显反映出数据包的乱序情况:

flowid packeid timerecvack  timesender timereceiver pt
1 1     0.8205     0.1080     0.4200 74
1 3     0.8365     0.1240     0.4360 74
1 5     0.8525     0.1400     0.4520 74
1 7     0.8685     0.1560     0.4680 74
1 9     0.8845     0.1720     0.4840 74
1 11     0.9005     0.1880     0.5000 74
0 0     0.9125     0.1000     0.5120 74
1 13     0.9165     0.2040     0.5160 74
0 2     0.9285     0.1160     0.5280 74
1 15     0.9325     0.2200     0.5320 74
0 4     0.9445     0.1320     0.5440 74
1 17     0.9485     0.2360     0.5480 74
0 6     0.9605     0.1480     0.5600 74
1 19     0.9645     0.2520     0.5640 74
0 8     0.9765     0.1640     0.5760 74

原有执行脚本上的拓补:

           ~~host0_if0~~          ~~host1_if0~~
          /   (1)200ms  \        /    (3)200ms  \
host0_core               -router-                -host1_core
          \   (2)100ms  /        \    (4)100ms  /
	    ~host0_if1~~           ~host2_if1~~ 
这种方式带来了路由上的歧义,才会导致仿真结果中一条路径的单向时延为0.3,另一个为0.4。因此在中间增加一个router,让host0_if0与host0_if1之间的路径唯一确定。

[1]rxc/log.c

[2]ns2自定义协议下载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值