NS2初学笔记(五)之 数据包流初探

来源:互联网 发布:debian和ubuntu 编辑:程序博客网 时间:2024/06/01 22:57
 

5,这一个问题应该洞悉ns2的核心问题了,所以即使我现还有很多问题没有搞懂,我依然把握对核心代码的一些理解写出来。

ns2中,应用代理使用来产生逻辑数据流或者说是数据流的发动者,而实际的数据流(包)却是在传输成代理(TCP/UDP等)那里产生的,我就的这样未免有点混乱——两个层面的代理需要相互的配合才能完成某一协议的模拟,不过既然是模拟这一点可能也就不重要了。要想理解数据的流动就不得不讲一下包的格式,以及模拟器对包的初始化过程。

首先:模拟器Simulatorinit过程有这么一步:

$self create_packetformat

该方法在ns-packet.tcl中定义:

Simulator instproc create_packetformat { } {

    PacketHeaderManagerinstvar tab_

    set pm [newPacketHeaderManager]

    foreach cl[PacketHeader info subclass] {

        if [infoexists tab_($cl)] {

            setoff [$pm allochdr $cl]

            $cloffset $off

        }

    } //这个for循环就是在为每一个包头计算它在包头栈中的偏移量,具体方法也在此文件中(不过还没    //仔细研究,呵呵)

    $self setpacketManager_ $pm

}

PacketHeaderManager set tab_(Common) 1 //还要主义这么一句,就是说如果用户没有添加任何的 //包头,系统也会自动初始化一个Common包头。添加包头的tcl方法也在此文件中。

现在,看到这里肯定有有一个疑惑了,计算偏移量干什么呢,当然是要寻址了(这点和编译过程有点类似),用户为了能够对包头进行操作,只要用到这个偏移量就可以,多方便。下面举一个例子,在AODV路由算法的实现中,包括了一个包头的定义hdr_aodv,这个头结构中有一个access方法,通过该方法(因为在初始化Simulator的时候就已经算好offset的值了)在任何时候访问到该包头中的内容

宏定义:

#define HDR_AODV(p)     ((structhdr_aodv*)hdr_aodv::access(p))

例如:

 struct hdr_aodv*ah = HDR_AODV(p);ah->ah_type

当然根据惯例为了Otclc++的互通要有一个类似于TclClass的类从当linkage

int hdr_aodv::offset_;

static class AODVHeaderClass : publicPacketHeaderClass {

public:

       AODVHeaderClass() : PacketHeaderClass("PacketHeader/AODV",

                                             sizeof(hdr_all_aodv)) {

      bind_offset(&hdr_aodv::offset_);

    }

} class_rtProtoAODV_hdr;

就是这个类实现了同TclClass一样的机制。Packet就是一个包,大部分情况下只包括一个包头,我们暂且就称Packet为数据也不为过了。

ns2中数据是大体是这么传输的(引自ns by example):

FTP发出指令,TCP实际分配数据,而通过分类器传给下一个目标节点。我是从创建节点开始分析的,但还没有分析通整个过程。

Ns2创建一个node的过程是这样的:

Simulator instproc node args {

    。。。。。

    set node[eval new [Simulator set node_factory_] $args]

            #defaultnode_factory_ is Node

   。。。。。

 

Node instproc init args {

    。。。。。

    $selfmk-default-classifier

    。。。。。

Node instproc mk-default-classifier {} {

    Node instvarmodule_list_

    # At minimumwe should enable base module

    foreachmodname [Node set module_list_] {

        $selfregister-module [new RtModule/$modname]

    }

}

Node instproc register-module { mod } {

    $self instvarreg_module_

    $mod register$self

    setreg_module_([$mod module-name]) $mod

}

RtModule/Base instproc register { node } {

    $self next$node

    $self instvarclassifier_

    setclassifier_ [new Classifier/Hash/Dest 32]

    $classifier_set mask_ [AddrParams NodeMask 1]

    $classifier_set shift_ [AddrParams NodeShift 1]

    # XXX Baseshould ALWAYS be the first module to be installed.

    $nodeinstall-entry $self $classifier_

}

看到这里,发现一个单播节点在初始化的时候只是加载了一个地址分类器,可是看一很久还是没有发现everything上面所说的端口分类器,这一点还有待研究(???)。

创建节点之后就是在节点之间创建链路(无线网络除外,但是有一个channel对象为其提供类似服务),然后attach代理(应该注意的是这个过程是在解释器端也就是用tcl代码实现的,还包括路由选择等过程我还没有弄懂(???)),最后就可以发送数据了。


如果大家去看/ns2.33/common里的代码,可以发现用于构建网络拓扑结果的器件(如connectoragent等等),凡是设计到数据发送的都有这么一个方法recv,其实这个也是必然的,因为大部分的类都是集成connectorclassifier,并且是在重写这个方法。Recv,顾名思义,就是用来接受数据的。而send方法有最后的一步就是target->recv(),所以任何一个数据包的流向都可以通过追踪recv来观察。这里只是粗略的说了一下,明白原理,毕竟我是个初学者,以后还要慢慢把细节补上。

 

6,软件调试是软件开发中的一项重要过程,同时反映调试信息的代码的编程量也是巨大的,而在ns2中网络模拟数据的采集其实就是输出软件调试信息,只是改把“探测器”放到那里的问题,“探测器”主要就是一些trace过程。只有探测到这些信息,才能利用分析工具进行分析。在/ns2.33/trace文件夹下,有

class Trace : public Connectortrace也是继承自connector说以可以看做是拓扑结构的一部分


:from ns by example

根据这个图我猜想,在建立link的时候trace就已经被安装在link中了,但是这个建立链路的过程以及ns2的整个建立拓扑结构的过程我还没有搞清楚,比如每个connnectortarget是怎么设置的,这个有待下一步研究(???)。

根据

class CMUTrace : public Trace {

。。。。。

    void   format_mac(Packet *p, int offset);

    void   format_smac(Packet *p, int offset);

    void    format_ip(Packet*p, int offset);

。。。。。

}可以猜想的到要想跟踪自己的协议数据,就要在这个类中添加自己的trace方法
原创粉丝点击