proc handle_fun {} {puts \ (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
$ns cancel
第七讲 (一)节点
[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 [
$ns node-config
$node id ;#返回节点的id号
$node node-addr ;#返回节点的地址(当地址类型为flat时,节点地址和它的id一样;当为hierarchical时,节点地址以一个字符串返回)
$node reset ;#重新设置绑定于节点的代理
#将绑定于节点上。如果用户没有指定端口号
$node attach
#与attach命令相反。该命令将代理从这个节点上撤除,然后在这个端口上绑定一个空代理,传入的分组将被空代理接收。
$node detach
NS2的链路(link)与TCP/IP网络中数据链路不同,它同时实现了物理层、数据链路层以及部分网络层的功能。
两台网络设备之间的通信按通信方式可分为:单工、半双工和全双工三种方式。 [1] 单向链路的创建
#创建一条node1到node2的单向链路,并且定义一些特性 set ns [new Simulator]
$ns simplex-link
[2] 单向链路的结构
一条简单的链路是由一系列的连接器(connector)逐步构成的。(像节点是由分类器组成的一样) 注意:
(1)NS有许多不同种类的连接器,每种连接器执行不同的功能;
(2)组成链路的Queues、DelayLink和TTLChecker都是Connector类的子类;
[3] 队列对象(Queues) 队列其实是一个缓冲区,用来存放或丢弃分组的地方。不同的队列类型拥有不同队列管理及分组的调度机制。
目前NS支持的队列类型有:
(a)丢弃队尾(Drop-tail)的先进先出队列
(b)RED缓冲区管理(随机早期检测(Random Early Detection))
(c)CBQ(包括优先级和轮换调度)即(Class-BasedQueuingCBQ,中文名称:基于类的队列) (d)各种公平队列(FQ、SFQ、DRR)
说明:CBQ是一种基于类的算法,根据流量特征处理数据包,并确保一定的传输速率。接收的数据包根据变量如差分服务代码点(DSCP:DifferentiatedServicesCodePoint)中的IP协议头、IP地址、应用程序或协议、URL或其它信息等进行分类。每类流量被分配到指定的FIFO(FirstInFirstOut)队列,其中每个队列的使用由部分路由器总带宽决定。如果队列为空闲,带宽便可以供其它队列使用。同时CBQ也是一种QoS方案,用于识别不同类型的流量并根据预置的参数对流量进行排队。 [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
$ns simplex-link
$ns simplex-link
$ns simplex-link-op
$ns duplex-link-op
;#设置节点n0到节点n1之间的链路的最大队列长度是10个分组的长度。
第八讲 代理
代理(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代码
[python]view plaincopyprint?
?? #创建UDP代理,假设节点n0和n1,以及模拟器对象ns已经建立 ??
?? set udp0 [new Agent/UDP] ;#创建一个UDP Agent
?? $ns attach-agent $n0 $udp0 ;#将UDP Agent绑定在节点n0上,作为分组的
发送器
?? $udp0 set packetSize_ 536 ;#设置UDP数据分组大小为536字节
?? set null0 [new Agent/Null] ;#创建一个空代理对象null0,作为分组的接收器 ?? $ns attach-agent $n1 $null0 ;#把null0绑定在节点n1上 ?? $ns connect $udp0 $null0 ;#在两个Agent之间建立连接
注意:
Agent/Null是空代理类,它通常和UDP代理配合使用,作为数据的接受者。空代理将接收到的分组不做任何处理直接丢弃。这一点说明空代理作为UDP代理的接收器是合适的,因为UDP协议是一种无连接的不可靠的协议,它并不要求接收端对分组做出任何响应。 [3] TCP代理
(1)TCP协议
(a)TCP协议即传输控制协议,提供了一个完全可靠(没有数据重复或丢失)、端到端的、面向连接的、全双工的字节流服务,允许两个应用进程建立一个连接,并在任何一个方向上发送数据,然后终止连接;
(b)每一个TCP连接可靠地建立,友好地终止,在终止前所有数据都会被可靠地传输;