1   问题引入

随着 Internet 的迅速发展,其网络规模越来越庞大,结构日趋复杂,仅仅依靠端到端的拥塞控制是不够的,网络本身也必须参与资源的控制和管理,在网络发生拥塞时,网络节点必须丢弃一些分组,这个问题的解决首先必须实施有效的队列管理机制。

队列调度算法运行在网络节点中发生冲突需排队等待调度之处,它按照一定的服务规则对交换节点的不同输入业务流分别进行调度和服务,使所有的输入业务流能按预定的方式共享交换节点的输出链路带宽。因此,网络的 QoS 能力与网络中采用的队列调度机制有着密切的关系。队列调度机制对数据包在网络中的传输具有较大影响,队列的调度算法对传输延迟、丢失率等性能指标也有着直接的影响。

本文对采用不同队列调度机制的网络分别进行了模拟,并对模拟结果进行分析,以此来比较网络 QoS 能力的变化。

2   网络 QoS 的相关指标

QoS通常是一种端到端概念,网络中任何瓶颈都会影响服务质量。网络QoS性能的量化指标包括带宽、延迟、延迟抖动、丢失率、吞吐量等。下面说明本文中会用到的几个性能指标和这些性能参数的计算方法:

(1)传输延迟

网络的传输延迟定义为源节点发送出第一个比特到目的节点接收到第一个比特之间的时间差,它包括电(或光)信号在物理介质中的传播延迟和数据在网中的处理延时(如复用/解复用时间、在节点中的排队和切换时间等)。简单的说,传输延迟是指网络中数据传输所用的时间。本文以数据包发送和到达之间的时间间隔来计算。计算公式如下:

R(n) = [TR (n) - TT(n)]

R( n)是第n个包的延迟。 TR (n)是第n个包收到的时间; TT (n)是第n个包发送的时间。

(2) 延迟抖动

延迟抖动又称为“可变延迟”,是网络传输延迟的变化量。指在同一条路由上发送的一组数据流中数据包之间的时间差异,以两个连续的包之间的不同间隔来计算,计算公式如下:

J ( n)= [TR(n) - TR(n - 1)] - [TT(n) - TT(n - 1)]

J (n)是第 n 个包的延迟抖动。TR (n)是第n个包的收到时间;TT (n)是第 n 个包的发送时间。一般,延迟抖动应低于延迟的 1%~2%。

(3)传输速率

网络的传输速率指单位时间内网络上传输的数据量。反映网络传输的能力。

(4) 丢包率

丢包率定义了传输期间网络丢失的数据包(分组)数量,丢包率通常指的是在特定时段内丢失的分组占传输的数据总量的比例。通常,当输入的分组远远超过输出队列的限制时会发生丢弃分组的现象,即由网络拥塞引起的;此外如果接收分组的缓冲区不够用时也会丢弃分组。以数据包的丢失数量与总发送数量的比值来计算。

(5) 吞吐量(S )

吞吐量是指网络传送二进制的速率,也称比特率,或带宽,通常指比特率。把单位时间内在信道上成功传输的信息量定义为吞吐量,即指单位时间内成功传送的无差错通信量。假设帧长为固定,长度为 L比特,且单位时间(以下设为秒)内成功传输的帧数为n 。则吞吐量可表示为nL bps(比特/秒)。

本文用的计算公式是:

S = N L / Tl

其中, N是采样时间段内网络中成功传送的无差错的帧数,L是帧的长度,Tl是采样时间段的长度。

(6)链路利用率

网络中的链路利用率指实际运行时的网络带宽占带宽容量的百分比,用传输速率与链路容量之比来计算。计算公式如下:

BR (n , i) = [BT(n, i) / Tl] / BN

其中, BR (n ,i)是第n 条链路在第i 个采样时间段的链路利用率。 BT (n ,i)是第i 个采样时间段内第n 条链路传输的数据总量; Tl是采样时间段的长度; BN是第n 条链路的链路容量,即带宽容量。

3   网络模型及参数

我们用 NS2 模拟建立一个简单拓扑结构的计算机网络,考察使用不同的队列管理策略时的网络性能的变化,这里比较 DropTail、RED 和 FQ(Fair Queuing)三种队列管理策略下的网络性能。计算机网络模型如图所示:

QOS 队列对赌 qos队列调度_算法

其中,节点0→2→3是UDP的连接,其上的业务是CBR服务;节点1→2→3是一个TCP的连接,应用层上运行的是FTP的服务,带宽设置为10Mb,链路延迟为10ms;节点2到3是一段瓶颈链路,由TCP和UDP连接共享,带宽设为2Mb,链路延迟为20ms。

4   TCL脚本

# 测试队列

# 使用方法为 ns queue_test DropTail(或者其它ns支持的队列名称)
if {$argc != 1} {
       puts "please specify one of the queue name"
       foreach queue [Queue info subclass] {
              puts $queue
       }
       exit 1
}
 
set ns_ [new Simulator]
set algo [lindex $argv 0]
 
# 设置要保存的文件
set tf [open "$algo.tr" w]
$ns_ trace-all $tf
set nf [open "$algo.nam" w]
$ns_ namtrace-all $nf
 
# 创建节点
set n0 [$ns_ node]
set n1 [$ns_ node]
set n2 [$ns_ node]
set n3 [$ns_ node]
 
# 创建节点间的链接
$ns_ duplex-link $n0 $n2 10Mb 10ms DropTail
$ns_ duplex-link $n1 $n2 10Mb 10ms DropTail
$ns_ duplex-link $n2 $n3 2Mb 20ms $algo
$ns_ queue-limit $n2 $n3 10  # 方便观察丢包现象
 
# 创建Agent并将之互联
set agent0 [new Agent/UDP]
$ns_ attach-agent $n0 $agent0
set agent30 [new Agent/Null]
$ns_ attach-agent $n3 $agent30
$ns_ connect $agent0 $agent30
 
set agent1 [new Agent/TCP]
$ns_ attach-agent $n1 $agent1
set agent31 [new Agent/TCPSink]
$ns_ attach-agent $n3 $agent31
$ns_ connect $agent1 $agent31
 
# 创建高层应用
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $agent0
set ftp [new Application/FTP]
$ftp attach-agent $agent1
 
# 设置仿真事件
$ns_ at 0.5 "$ftp start"
$ns_ at 0.5 "$cbr start"
$ns_ at 3.5 "$ftp stop"
$ns_ at 3.5 "$cbr stop"
$ns_ at 4.5 "finish"
 
 
proc finish {} {
       global ns_ algo
       $ns_ flush-trace
       puts "$algo queue test finished success"
       exit 0
}
 
$ns_ run

 

5   模拟数据及其格式

在仿真结束之后,将生成两个文件,一个是NAM文件,一个是TR文件。其中NAM文件是给NAM程序进行动态演示时使用的,在此不做分析。而TR文件则记录了所有数据包的流向,对网络参数的分析主要就是对TR文件的分析。

计算机模拟生成的部分跟踪数据(.tr 文件)如下:

+ 0.5 1 2 tcp 40 ------- 0 1.0 3.1 0 0

- 0.5 1 2 tcp 40 ------- 0 1.0 3.1 0 0

+ 0.5 0 2 cbr 210 ------- 0 0.0 3.0 0 1

- 0.5 0 2 cbr 210 ------- 0 0.0 3.0 0 1

其中,第一个符号表示报文当前的操作状态,即报文的进队(+)、出队(-),接收事件(r)和丢弃事件(d);

第二项是当前的模拟时间,即事件动作发生的时间;

第三、四项是数据报文在两个节点之间传输的对应节点号;前者是发送节点,后者是接收节点;

第五项是所发送报文的类型;

第六项是数据报文的大小;

第七项是表示特殊的标志位,当标志位使能时才显示;

第八项是为IPv6定义的IP标识域;

第九、十项是显示数据报文的源和目的节点的地址,注意这两个数看着像是一个浮点数,如(3.1,3.0),但其实它们只是用点号分开的两个数据,小数点之前表示节点号,小数点之后表示在此节点上的Agent序号;

第十一项是显示顺序号,这是为了和NS1兼容而设置的;

最后一项是分组号,显示当前传输的报文的分组编号。

6   模拟结果分析

由于TR文件是一种具有良好结构性的文件,因此非常适合于使用gawk进行分析,以下的分析代码均为awk脚本,且放在queue.awk中,使用gawk –f queue.awk *.tr这样的命令进行调用。采用的数据文件为DropTail算法生成的DropTail.tr。

1、 节点0发送的数据包统计:

BEGIN {n = 0}
(($1 == "+") && ($3 == "0")) {n += 1}
END {print n}
结果为800

2、 节点1发送的数据包统计

BEGIN {n = 0}
(($1 == "+") && ($3 == "1")) {n += 1}
END {print n}
结果为359

3、 丢弃的CBR包统计

BEGIN {n = 0}
(($1 == "d") && ($5 == "cbr")) {n += 1}
END {print n}
结果为5

4、 丢弃的TCP包统计

BEGIN {n = 0}
(($1 == "d") && ($5 == "tcp")) {n += 1}
END {print n}
结果为12

5、 节点0到节点3的数据包的平均时延统计

BEGIN {
       n = 0
       tm = 0
       }
(($1 == "+") && ($3 == "0")) {begin_time[$12] = $2}
(($1 == "-") && ($4 == "3")) {
       if($ 
    
      12 in 
     begin_time) {
              n += 1
              tm += $2 - begin_time[$12]
       }
}
END {print tm / n}
结果为0.0159941,即15.9941毫秒

6、 节点0到节点3的投递率

(800 – 5) / 800 = 0.99375

7、 节点2到节点3的链路利用率

BEGIN {
       begin_time = 0
       end_time = 0
       packet = 0;
       }
(($1 == "r") && ($3 == "2") && ($4 == "3")) {
       packet += $6
       if($2 > end_time) end_time = $2
       if(begin_time == 0) begin_time = $2
}
END {print packet * 8 / (end_time - begin_time) / 2e6}
运算结果为0.702422