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

来源:互联网 发布:jaycn淘宝店是谁开的 编辑:程序博客网 时间:2024/06/03 21:16

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

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

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

#ifdef __cplusplusextern "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 messagesPing # Ping    PBC     # PBCMpUdpMpUdpAck

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

//ns-lib.tcl?line=1516Simulator 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_ $addrlappend binding_ $portlappend 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 herestatic 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 onename_[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 DropTailset 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 pt1 1     0.8205     0.1080     0.4200 741 3     0.8365     0.1240     0.4360 741 5     0.8525     0.1400     0.4520 741 7     0.8685     0.1560     0.4680 741 9     0.8845     0.1720     0.4840 741 11     0.9005     0.1880     0.5000 740 0     0.9125     0.1000     0.5120 741 13     0.9165     0.2040     0.5160 740 2     0.9285     0.1160     0.5280 741 15     0.9325     0.2200     0.5320 740 4     0.9445     0.1320     0.5440 741 17     0.9485     0.2360     0.5480 740 6     0.9605     0.1480     0.5600 741 19     0.9645     0.2520     0.5640 740 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自定义协议下载

原创粉丝点击