[转载]NS2架构zz

来源:互联网 发布:app源码是什么 编辑:程序博客网 时间:2024/04/27 19:39

NS2的离散事件调度机制

[1] Simulator类
在NS2中,每个网络模拟过程需要一个类对整个过程进行控制和管理,这个类就是模拟器类(Simulator类)。
注意:
(1)整个模拟过程可以看作是对模拟器类对象的操作;
(2)模拟器类是一个解释类,没有相应的编译类,封装了节点(node)、链路(link)、代理(agent)、数据分组格式等。
(3)整个模拟过程从创建一个模拟器类对象开始,通过调用这个对象的各种过程实现:创建节点、构建拓扑结构图、对模拟的各个方面进行配置、定义事件、根据定义的事件模拟整个网络的运行等。

创建一个模拟器类对象:
set ns [new Simulator]   ;#新建一个Simulator对象ns(后面要使用这个ns对象,必须在前面加$)
与此同时完成了下列一系列的初始化操作:
(a)初始化分组格式(调用create_packetformat);
(b)创建一个事件调度器(scheduler,缺省为calendar scheduler);
(c)创建一个空代理(null agent);

[2] NS2的事件和事件调度器
NS2是一个事件驱动的模拟器。
注意:
(1)一个NS2事件通常包含两个部分:(a)事件的触发时间;(b)用来处理事件的功能函数的句柄;
NS2模拟器内部at过程的主要功能是在特定的时间调用事件处理函数处理事件。
例如:
#下面这段Tcl代码首先创建了模拟器对象ns,由事件调度器在5秒时,调用执行handle_fun函数
set ns [new Simulator]
$ns at 5.0 "handle_fun"
$ns run
proc handle_fun {} {puts "This is the event handle function!"}
(2)事件调度器的工作过程:
事件调度器其实就是一个事件队列,所有的事件按事件的触发时间排列。当时间到达某一事件的触发时间时,事件调度器选择该事件出队,同时调用事件处理函数执行完该事件,如此反复执行上述过程。
如果在同一时刻,有多个事件需要执行,事件调度器将按照先调度先执行(first scheduled-first dispatched)的原则进行调度。
目前NS2支持四种事件调度器:
(a)链表式(linked-list)调度器
(b)堆式(heap)调度器——适用于有大量事件的情况
(c)时间队列式(calendar)调度器——默认的事件调度器
(d)实时(real-time)调度器

[3] 相关命令
set ns [Simulator]           ;#创建一个模拟器对象
set now [$ns now]          ;#将调度器的当前时间赋值给now变量,以便在模拟时跟踪时间
$ns halt                          ;#停止或暂停调度器
$ns run                           ;#启动调度器
$ns at <time> <event>   ;#在一个特定时间<time>调度一个事件<event>
$ns cancel <event>         ;#取消<event>事件,将事件从准备好的调度器中删除


 

(一)节点

[1] 单播和多播
根据网络节点之间通信方式的不同,分组的传输方式有两类:单播(unicast)和多播(multicast)。在NS2中设计了两类网络节点即单播节点和多播节点来实现以上两种不同的通信方式。

[2] 单播节点的创建
NS2默认创建的是单播节点:
#创建了一个单播节点n0
set ns [new Simulator]
set n0 [$ns node]

[3] 单播节点的结构
一个单播节点是一个组合对象,主要包括两个Tcl对象:地址分类器(address classifier)和端口分类器(port classifier)
注意:
(1)一个节点本质上是一个分类器的集合,一个简单的单播节点主要由地址分类器和端口分类器组成;
(2)每种不同的分类器分别查看分组的一个特殊部分,再依次转发分组;
(3)地址分类器的主要功能是用来判断分组的地址,转发分组到下一个接收器;
(4)端口分类器的主要功能是按照分组的目的端口进行匹配,将分组传递给相应的agent对象;

[4] 多播节点的创建
首先必须将模拟器对象ns内部的-Multicast属性值设置为on,然后调用node过程创建多播节点。
#创建一个多播节点n1
set ns [new Simulator -Multicast on]
set n1 [$ns node]
注意:
(1)一旦-Multicast的属性值设置为on,在此之后调用$ns node过程建立的节点都将是多播节点,如果要再创建单播节点,必须先将-Multicast的值重新设为off。

[5] 多播节点的结构
多播节点主要由多播分类器(Multicast Classifier)和复制器(Replicator)组成。
注意:
(1)多播节点包含复制器(Replicator)对象,并使用其生成分组的拷贝。

[6] 节点的配置
大部分情况下使用NS2是对无线网络做一些研究工作。在NS2中要创建一个移动节点,就必须在创建节点之前对节点进行配置。
节点的配置:就是在节点创建之前设定节点的各项属性,可以使用模拟器对象ns的内部过程node-config{}来配置节点的属性。
注意:(P.47 表3.1 节点所有可配置的属性)
(1)所有节点可配置的属性
(2)卫星节点和无线节点都可配置的属性
(3)仅无线节点可配置的属性
(4)仅卫星节点可配置的属性

[7] 与节点相关的命令
$ns node [<hier_addr>]      ;#创建和返回一个节点对象
$ns node-config <config-parameter> <optional-val>   ;#用于配置节点属性,-reset选项用于将节点属性配置为默认值
$node id                ;#返回节点的id号
$node node-addr  ;#返回节点的地址(当地址类型为flat时,节点地址和它的id一样;当为hierarchical时,节点地址以一个字符串返回)
$node reset          ;#重新设置绑定于节点的代理

#将<agent>绑定于节点上。如果用户没有指定端口号<port_num>,节点将自动为其分配一个端口号,并将该代理绑定到节点上。一旦代理绑定,代理将接收从该节点的端口传来的分组。
$node attach <agent> <optional:port_num>   

#与attach命令相反。该命令将代理从这个节点上撤除,然后在这个端口上绑定一个空代理,传入的分组将被空代理接收。
$node detach <agent> <null_agent>  

(二)链路

NS2的链路(link)与TCP/IP网络中数据链路不同,它同时实现了物理层、数据链路层以及部分网络层的功能。
两台网络设备之间的通信按通信方式可分为:单工、半双工和全双工三种方式。

[1] 单向链路的创建
#创建一条node1到node2的单向链路,并且定义一些特性
set ns [new Simulator]
$ns simplex-link <node1> <node2> <bandwidth> <delay> <queue_type>

[2] 单向链路的结构
一条简单的链路是由一系列的连接器(connector)逐步构成的。(像节点是由分类器组成的一样)
注意:
(1)NS有许多不同种类的连接器,每种连接器执行不同的功能;
(2)组成链路的Queues、DelayLink和TTLChecker都是Connector类的子类;

[3] 队列对象(Queues)
队列其实是一个缓冲区,用来存放或丢弃分组的地方。不同的队列类型拥有不同队列管理及分组的调度机制。
目前NS支持的队列类型有:
(a)丢弃队尾(Drop-tail)的先进先出队列
(b)RED缓冲区管理
(c)CBQ(包括优先级和轮换调度)
(d)各种公平队列(FQ、SFQ、DRR)

[4] 延迟链路对象(DelayLink)
主要用来模拟链路延迟和带宽特性的对象。

[5] TTL检查器对象(TTLChecker)
将收到分组的TTL值减1。如果TTL值为正,分组将被送至链路上的下一个元素;否则,分组将被丢弃。
TTL(Time to Live)代表了分组的生存期,是分组中的一个域,它告诉网络分组在网络中的时间是否太长而应该被丢弃。TTL通常表示分组在被丢弃前最多能经过的路由器个数。当记数到0时,路由器决定丢弃该分组,并发送一个ICMP报文给最初的发送者。

[6] 双向链路的创建
#创建一条node1到node2的双向链路,并且定义一些特性
set ns [new Simulator]
$ns duplex-link <node1> <node2> <bandwidth> <delay> <queue_type>
一条双向链路其实是由两条方向不同的单向链路构成,所以等价于:
set ns [new Simulator]
$ns simplex-link <node1> <node2> <bandwidth> <delay> <queue_type>
$ns simplex-link <node2> <node1> <bandwidth> <delay> <queue_type>

[7] 与链路相关的NS命令
$ns simplex-link <node1> <node2> <bandwidth> <delay> <queue_type>
$ns duplex-link <node1> <node2> <bandwidth> <delay> <queue_type>

$ns simplex-link-op <node1> <node2> <option> <args> ;#设置单向链路的属性,主要包括方向、颜色等,用于Nam的动画显示
$ns duplex-link-op <node1> <node2> <option> <args>


 

代理

代理(Agent)可以构建和销毁网络层的分组,是网络层分组的起点和终点,同时,代理还可以实现各种不同层的网络协议。
例如:
NS2中的Agent/TCP和Agent/UDP分别实现了传输层的两个重要协议即TCP和UDP。
注意:
(1)在NS2中,所有的OTcl类都是从SplitObject类一级级继承出来的,NS2使用了一种以字符“/”作为分割符的类命名规则来表示一个OTcl类从SplitObject开始的继承关系。


[1] Agent类
Agent类是由C++和OTcl共同实现的。
对于代理的使用者来说,只需知道使用此特定代理的OTcl Agent中的内部变量。
例如:
OTcl中的Agent/UDP类内部变量packetSize_实际上是与C++中的UDP Agent中的size_绑定在一起的,只需创建一个Agent/UDP对象,并使用set命令设置packetSize_的值,这时,packetSize_的值将自动赋给C++ Agent类中size_变量。

注意:
NS2支持的各种协议代理,每一种协议代理都是Agent类的子类。


[2] UDP代理

(1)UDP协议
(a)是一种无连接的传输层协议,提供面向事物的简单的不可靠的信息传送服务;
(b)UDP没有流量控制机制,收到分组时也不对分组进行确认;
(C)UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境;
(d)UDP对应的应用层协议,包括网络文件系统(NFS)、简单网络管理协议(SNMP)、域名系统(DNS)以及简单文件传输协议(TFTP)

(2)Agent/UDP
Agent/UDP类是Agent类的一个子类,模拟了UDP协议的主要功能。
NS2创建和设置UDP代理可以分为以下几步:
<步骤1> 创建一个Agent/UDP对象并将其绑定到相应的节点上作为分组的发送器。
<步骤2> 设置Agent/UDP的部分内部变量。
<步骤3> 创建一个Agent/Null对象并将其绑定到相应的节点作为分组的接收器。
<步骤4> 在两个发送和接受代理之间创建connect连接。

Tcl代码

 

+ expand sourceview plaincopy to clipboardprint?

     

    注意:
    Agent/Null是空代理类,它通常和UDP代理配合使用,作为数据的接受者。空代理将接收到的分组不做任何处理直接丢弃。这一点说明空代理作为UDP代理的接收器是合适的,因为UDP协议是一种无连接的不可靠的协议,它并不要求接收端对分组做出任何响应。


    [3] TCP代理

    (1)TCP协议
    (a)TCP协议即传输控制协议,提供了一个完全可靠(没有数据重复或丢失)、端到端的、面向连接的、全双工的字节流服务,允许两个应用进程建立一个连接,并在任何一个方向上发送数据,然后终止连接;
    (b)每一个TCP连接可靠地建立,友好地终止,在终止前所有数据都会被可靠地传输;
    (c)TCP使用“三次握手”的方式建立一个连接,数据传输完成之后,任何一方都可以断开连接;也就是说,一个应用进程开始传送数据到另一个应用进程之前,它们之间必须建立连接,需要相互传送一些必要的参数,以确保数据的正确传输;
    (d)TCP协议确保通过一个连接发送的数据能够被接收端正确无误地接收,且不会发生数据丢失或乱序;

    TCP使用以下机制确保服务的可靠性:
    (a)选择合适发送的数据块大小,并赋予序列号
    TCP连接一旦建立,应用程序就不断地把数据先发送到TCP发送缓冲区(TCP sendbuffer),接下来,TCP就把数据流分成块,再添加TCP协议的头部(TCP header)形成TCP报文段。这样就将应用程序数据封装成了传输协议数据单元(TPDU)。这些报文段送到网络层,由IP协议封装成IP数据报之后发送到网络上。

    (b)对发送的TPDU启动计时器,超时重发
    当TCP发出一个报文段后,就启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。可以根据不同需要设定各种重传策略。

    (c)对正确接收的TPDU进行确认
    当TCP收到发自TCP连接另一端的报文段后,将发送一个确认。这个确认不是立即发送的,通常要推迟(为什么?)。

    (d)识别并丢弃重复的TPDU
    既然TCP报文段封装成IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据报进行重新排序,将收到的数据报以正确的顺序交给应用层。由于IP数据报会发生重复,因此TCP的接收端必须丢弃重复的TPDU。

    (e)提供流量控制(实行缓冲区管理)
    TCP协议采用滑动窗口机制实现流控。窗口的大小表示在最近收到的确认号之后允许传送的数据长度。连接双方的主机都为TCP连接分配了一定数量的缓存。每当进行TCP连接时,接收端主机只允许发送端主机发送的数据不大于其缓存空间的大小。也就是说,数据传输的流量大小由接收端确定。如果没有流量控制,发送端主机就可能以比接收端主机快得多的速度发送数据,使得接收端的缓存出现溢出。

    (2)Agent/TCP
    NS2中有两类TCP代理:单向代理(one-way agent)和双向代理(two-way agent)
    (a)单向代理包括一系列的TCP发送者(依照拥塞算法和差错控制算法的不同)和接受者(TCPSink)。
    (b)双向代理本身既可以作为发送者也可以作为接受者。

    主要考虑TCP的单向代理,以Agent/TCP(Tahoe TCP)和Agent/TCPSink为例。

    NS2创建和设置TCP代理可以分为以下几步:
    <步骤1> 创建一个Agent/TCP对象,作为分组的发送器。
    <步骤2> 设置Agent/TCP对象的部分内部变量。
    <步骤3> 创建一个Agent/TCPSink对象,作为分组的接收器。
    <步骤4> 在发送和接受代理之间创建connect连接。

    Tcl代码

     

    view plaincopy to clipboardprint?
    1. #创建TCP代理,假设节点n0和n1,以及模拟器对象ns已经建立  
    2.   
    3. set tcp [new Agent/TCP]              ;#创建一个TCP源代理对象tcp  
    4. $ns attach-agent $n0 $tcp            ;#把这个TCP源代理绑定在节点n0上  
    5. $tcp set fid_ 1                      ;#设置IP层数据流fid  
    6. $tcp set window_ 20                  ;#设置TCP滑动窗口的大小为20  
    7. set sink [new Agent/TCPSink]         ;#创建分组的接收代理对象  
    8. $ns attach-agent $n1 $sink           ;#将接收器sink代理绑定到节点n1上  
    9. $ns connect $tcp $sink               ;#在两个Agent之间建立连接  

     

    注意:
    在单向代理中,TCP源代理负责发送TCP数据分组,而TCPSink对象负责接收数据分组,并发送确认ACK分组,可以通过设置packetSize_的值来设置所有ACK分组的大小。


    [4] 其他协议Agent
    NS2中除了支持UDP、TCP协议外,还支持许多其他的协议,这些协议都是通过继承Agent来实现的。

    #查看NS2支持的各种协议的Agent

     

    view plaincopy to clipboardprint?
    1. proc showAgent {arg}  
    2.        foreach [$arg info subclass]  
    3.          puts $c  
    4.          if {[$c info subclass] != ""}  
    5.               showAgent $c  
    6.           
    7.         
    8.  
    9. showAgent "Agent"  

     


    [5] 与Agent相关的命令
    set agent [new Agent/AgentType]       ;#创建一个新的代理对象
    $n attach-agent <node> <agent>       ;#在<node>上绑定一个<agent>,假定<agent>已经创建
    $agent port                                          ;#返回绑定的agent端口号
    $agent dst-port                                    ;#返回目标端口号
    $agent attach-app <s_type>               ;#在agent上绑定一个类型为<s_type>应用
    $ns connect <src> <dst>                     ;#在src和dst之间创建一条连接,假定src和dst代理已经创建
    $ns create-connect <srctype> <src> <dsttype> <dst> <pktclass>   ;在两个代理之间创建一条完整的连接
    $agent attach-trace <file>                   ;#将<file>绑定到agent上,允许Nam对Agent事件的跟踪


     

    应用层

    在NS2中,业务流是由应用层产生的。

    [1] 应用层概述
    在NS2中,应用层程序构建在传输层之上,它分为两大类:流量产生器(traffic generator)和应用模拟器(simulated application)。
    注意:
    (1)流量产生器一般用在UDP代理之上;应用模拟器一般用在TCP代理之上。
    (2)NS2通过在传输层Agent内部预定义一些成员函数来模拟socket API的功能。
    (3)Application类是OTcl中应用层程序的基类,提供了应用层程序的一些行为的基本原型。
    (4)可以通过Tcl代码查看NS2中能够实现的各种应用程序。(P.61)

    [2] 流量产生器(Traffic generators)
    网络中的业务流是随机产生的,因此,以某个固定速率来模拟实际业务流的产生情况显然是不合适的。为此,NS2中创建了各种不同的概率模型来模拟产生实际网络中的业务流。
    在NS2中,根据业务流产生的概率模型的不同,实现了4种流量产生器(一般都是建立在UDP代理之上)。

    (1)指数分布流量产生器
    在OTcl中对应的类名为Application/Traffic/Exponential。
    该流量产生器按照指数On/Off分布产生数据。在"On"阶段,分组以固定的速率发送;在"Off"阶段,分组停止发送。"On"和"Off"两种状态的时间都符合指数分布。

    (2)泊松分布流量产生器
    在OTcl中对应的类名为Application/Traffic/Pareto。
    该发生器除了"On"、"Off"两种状态之间的时间产生业务流符合Pareto分布外,其他时间按指数On/Off分布。这种分布可用来产生长时间相关的急剧通信量。

    (3)固定比特流量产生器
    在OTcl中对应的类名为Application/Traffic/CBR。
    该流量产生器按照一个固定的速率产生业务流,分组的长度为一常数值,可以选择需要时对分组发送的时间间隔产生随机抖动。

    (4)Trace文件流量产生器
    在OTcl中对应的类名为Application/Traffic/Trace。
    该流量产生器按照一个Trace文件产生数据。

    例子:

    view plaincopy to clipboardprint?
    1. #在UDP上配置一个CBR流量发生器的的基本步骤  
    2. #假设模拟器对象ns、节点n0和n1已经创建,数据流从n0到n1  
    3.   
    4. #创建传输层代理对象并将传输层代理绑定到相应的节点上  
    5. set src [new Agent/UDP]  
    6. set sink [new Agent/Null]  
    7. $ns attach-agent $n0 $src  
    8. $ns attach-agent $n1 $sink  
    9.   
    10. #创建流量产生器对象,设置对象属性(可选),并将其与传输层的源代理绑定  
    11. set [new Application/Traffic/CBR]   ;#创建一个流量产生器对象  
    12. $e set packetSize_ 300                ;#设定数据分组的大小为300字节  
    13. $e set rate_ 32kb                     ;#设定数据的发送速率为32kb  
    14. $e set random_ On                     ;#在分组的发送时间上加入随机“噪声”  
    15. $e attach-agent $src                  ;#将流量产生器对象与源代理绑定  
    16.   
    17. #启动和停止流量产生器  
    18. $ns at 0.0 "$e start"                 ;#在0.0秒启动流量产生器  
    19. $ns at 5.0 "$e stop"                  ;#在5.0秒停止流量产生器  

     

    [3] 应用模拟器(Simulated application)
    建立在TCP代理之上的业务流需要使用应用模拟器来产生。
    (1)FTP应用模拟器
    对应的OTcl类为Application/FTP。主要用来模拟大量数据的传送。

    (2)Telnet应用模拟器
    对应的OTcl类为Application/Telnet。

    例子:

    view plaincopy to clipboardprint?
    1. #在TCP上使用FTP  
    2. set src [new Agent/TCP]  
    3. set sink [new Agent/TCPSink]  
    4. $ns attach-agent $n0 $src  
    5. $ns attach-agent $n1 $sink  
    6. $ns connect $src $sink         ;#在源代理和接收代理之间创建TCP连接  
    7.   
    8. set ftp [new Application/FTP]  
    9. $ftp attach-agent $src  
    10. $ns at 0.5 "ftp start"  
    0 0
    原创粉丝点击