钟 辉,周甜甜
(沈阳建筑大学 信息与控制工程学院,沈阳 110168)
无线路由协议由先验式和和按需路由协议组成.按需路由协议不需要周期性与邻接点交换路由信息来维护整个网络的路由表,而是在节点需要给目的节点发送数据分组时来寻找到达目的节点的路由,因此控制开销较小.路由信息可以得到有效的利用[1].在按需路由协议中,AODV(Ad Hoc on-demand distance vector)协议的路由开销相对较少,收敛性快,有明显的优势,但随着数据量的激增,单路径路由协议AODV显然已不能满足需求,在基于AODV扩展的多路径路由协议中,AOMDV多路径路由协议在AODV协议基础上,实现了获取多条无环路、且节点不相交路径完成路由表包含多条有效路径[2].其主要缺点是没有考虑链路的传输压力,缓存队列长度有限,若队列中缓存的分组没有被及时发送出去,后到达的分组将会因为当前队列占有率过大而被丢弃,造成数据包的丢失,降低网络的吞吐量,队列中没有被及时发送出去的分组也会增加不必要的排队时延,增加端到端延时,浪费网络资源.针对AOMDV路由协议对此造成的不良影响,本文提出一种基于启用实时监测链路传输压力的多路径路由协议QE_AOMDV.
AOMDV路由协议是对AODV单路径路由协议进行了多路扩展,它是充分将RREQ请求分组的泛洪特性使用在路由请求过程,促使多条节点不相交路径在广播中建立[3].
在路由请求过程中,AOMDV多路径路由协议和AODV协议相似,基于序列号来表明路径的新旧,以保证不产生环路路径.AOMDV协议中为了使目的节点序列号保持单调递增,协议定义了“广告跳数(Advertised HopCount)”的概念来产生目的节点序列号.任何源节点到目的节点的广告跳数使用其间多条路径中有“最大”跳数的有效路径来表达.确定了最大跳数,任何目的节点序列号广告跳数都始终不变.而AOMDV协议只使用跳数小于最大跳数的备选路由表项.源节点寻早目的节点路由时就开始广播 RREQ 分组,当RREQ分组到达中间节点时,可能有多个RREQ分组到达,检查每个RREQ分组中firsthop字段和节点的最后一跳列表,检查此路由是否来自源节点的不同邻居节点,因此来判断RREQ分组内容能否提供没有使用过的节点不相交路径[4].据此目的节点或者具有有效路由中间节点产生RREP分组,将RREP 分组单播回传到源节点.多个RREP分组到达源节点,最后多条节点不相交路径在源节点路由表中产生出来.AOMDV协议的路由发现机制选择跳数最少的路径作为传输主路径,剩余的路径称为备份路径.若输主路径失效,分组的传输就用备份路径来代替主路径进行,一直至运行至路由表中所有备份路径都失效,再由源节点开启一轮新的寻路过程[5].
路由维护发生在链路断裂时,如果当前节点到目的节点的跳数小于源节点到当前节点的跳数,则进行本地路由修复.即如果当前节点正在传输数据,链路发生异常,则缓存数据,将该节点标记为RTF_IN_REPAIR,并向目的节点发送一个路由发现请求.如果在定时器规定时间内,没有找到当前节点到目的节点的有效路由,将该路由释放,丢弃缓存的数据包,发送RRER错误分组至上流节点,通知上游节点避免使用所有经过该节点的路由[6].
首先数据包在应用层(Application::send)向下发送到代理Agent层;代理Agent层(UdpAgent::sendmsg)初始化Agent代理生成其代理对象UdpAgent.UdpAgent对象产生对应的数据分组,并将分组传入到Node节点的分类器Classifier(Classifier::recv)对象,该对象调用find()函数返回下一跳地址.在Packet包对象内容中是由Find()函数查找获得Packet包的下一跳地址的,分类器recv 函数分组的下一跳地址后调用节点node->recv()函数进入connector对象;然后再调用connector::recv函数和 connector::send函数后确定数据包是否可发送,之后进入Trace::recv函数,此时将这个数据包加入队列的记录保存起来;之后再由 connector::send函数进入Queue::recv 函数,将数据包正式加入发送队列,判定是否加入队列成功或被丢弃;然后再调用 DequeTrace::recv函数将数据包弹出队列的记录保存起来;最后再通过connector::send函数调用进入LinkDelay::recv方法,首先进行目的节点是否可达的判断,再根据不同结果将事件写入scheduler对象,等待NS事件调度执行.
队列代表存放(或者丢弃)包的地方,在网络中DropTail管理机制是最广泛使用的队列管理机制[7].当某个数据包到达队列时,增加包到队列尾部而等待,考虑存储空间限制造成等待队列长度设置有限,大量数据流通过网络时,由于队列没有足够的空间,这些刚到达的数据包就无法进入队列保存,因此简单的将队列尾部的数据包丢弃,称这样的管理机制为DropTail.整个运作方式为:包传送的顺序与包进入队列的顺序相同,先进入队列的包先传送出去,后进入队列的包等待前面的包传送完成后再传送出去.如果队列长度超过暂存空间的大小,就会把队列最尾端的包丢弃[8].
DropTail在丢弃包时,并不会去考虑要丢弃的包属于哪个数据流,只是单纯的把超过暂存空间大小的数据流丢弃,因此DropTail队列管理机制的最大优点就是实际操作简单.但是,有利有弊,在相当长一段时间内,这种单一特性的操作使得队列处于满负荷或几乎满负荷状态.本文提出的队列管理机制最重要目的是降低稳定状态下队列的长度,因为大部分端点到端点的延迟其主要原因是数据包在缓存队列中排队等待造成的[9].
DropTail队列列管理也容易产生TCP全局同步(TCP Global Synchronization)现象.因为网络上数据流都具有突发性,因此到达每个路由器的包也是突发的.当每个路由器暂存队列处于满负荷或几乎满负荷状态,大量的数据包会在短时间内被丢弃.而在TCP协议下数据流具有自适应特性,发送端检测出数据包丢失就会立刻降低发送速度,缓解网络拥塞状况.发送端发现网络拥塞缓解后又开始增加发送速度,最终又造成网络拥塞.这种现象形成一个循环,周而复始的进行下去,会致使网络长期处于链路利用率很低的状态,降低了整体的吞吐量[10].为了克服这种TCP全局同步现象,如果能实时检测到队列中缓存区的状态,则可以及时掌握网络拥塞情况,对全局同步现象做出预判,改善网络性能.对此在第4部分提出基于DropTail的主动丢包队列管理机制.
本文提出的基于DropTail的主动丢包队列管理机制吸取了RED算法的思想,事先在队列中随机检测队列容量.随机提前检测RED算法使用主动的管理队列的方式.其主要算法过程是:在网络路由器存满接收到的包之前随机检测队列容量,按事先确定的规则随机丢弃包分组,这样能够事先告诉发送端缩小拥塞窗口,对进入网络包分组加以控制,防止路由器将更多的分组随意丢弃.
RED算法主要分为两种计算内容:1)平均队列长度计算,指在时间上平均,该算法路由器的各个接口只有一个队列;2)分组丢失概率计算.第一部分决定了路由器能够允许的突发分组发送的程度,第二部分决定了路由器在当前满队列状态下分组丢弃的频度,主要目的是让路由器在时间间隔均匀的情况下丢弃分组,避免对突发性数据流的不公平性,同时防止TCP全局同步产生,还要能足够频繁地丢弃分组以控制队列的平均长度.使用平均队列长度比使用队长的瞬时值更能准确的观测到网络的拥塞情况[11].
Drop Tail是广泛使用的队列管理机制.它类似于FIFO(先入先出)的管理,先到达路由器的分组先被传输,原理相对简单.路由器缓存队列充满数据时,利用丢包进行拥塞检测.但路由器队列缓存空间收大小限制,如果在路由缓存充满时还有分组到达,那就丢弃该分组.若发生丢弃分组现象,立即告知发送端网络出现拥塞,调整发送速率.这种方法的缺点是不考虑被丢弃包的重要程度.
队列类是由一个连接器基类派生的,该基类可以派生出各种队列类.队列类Queue部分伪代码如下:
Queue 继承Connector{
纯虚函数enque()
纯虚函数deque()
接收函数recv()
获取队列初始长度limit()
获取队列实时长度length()
队列最大包个数qlim_
……
}
enque和deque函数是纯虚函数,代表包的入列和出列,任何类型的队列在实现Queue这个基类时,都必须实现enque和deque两个函数.其中,qlim_代表队列所允许的最大的包的个数,limit()函数返回值是qlim_,即limit()函数的返回值是队列设定的初始长度,length()函数返回当前队列中缓存区的包的个数,即缓存区的队列长度.DropTail继承自Queue类,本文通过调用limit()和length()这两个函数在路由层跨层获取MAC层的队列长度来改进包的发送策略.
网络Mac层就是用接收来的包充满缓冲区时,看是否丢弃包来判断网络拥塞.遵循先进先出原则,位于队列中前面的包将率先被发送出去[12].如果此时队列缓冲区已满,那么后到达的包将被丢弃.
只有一个先进先出(FIFO)队列存在于DropTail管理机制,由包队列类的对象实现.DropTail队列机制实现了自己的enque()函数和deque()函数.enque()函数首先在队列内部判断qlim_参数检测队列的容量,当队列中的包数量达到或者超过队列最大长度时,丢弃最近接收的包.队列类实现了缓冲区管理,但是却不能在特定队列上实现低层次的操作.解决这个问题的有效方法是使用包队列类.
该类是设置成一个包的链表,包的顺序一般用特殊的调度和缓冲管理规则用来存储.其中,length()函数返回当前队列中包的数量,即队列此时缓冲区的长度,enque()函数将特定的包加在队尾并修改成员变量len_,deque()函数返回队列头部的包.lookup()函数返回从队列首部第n个包,若找不到,则返回空.
原始的队列管理机制DropTail原理非常简单,就是当路由器缓冲存满时用丢包来警示网络拥塞,包先到先被传输,若包到达时缓存已满,丢弃分组,告知发送端网络拥塞,调整发送端发送速率[13].
综上所述,在原AOMDV路由协议中,包队列始终处于队列达到最大值就丢弃后来的包,无法利用队列状态对即将到来的包做出预判.无论当前节点是否处于满载状态,都将采用当前节点进行包的传输.如果节点此时的队列缓冲区空闲,即时发送,如果有未发送的包且队列未达到最大长度,则将该包入列,等待前向包发送完成之后在发送.如果此时队列中已达到最大长度,则直接丢弃该包.原始的队列管理机制没有充分利用队列状态,对节点是否是传输包的适宜节点作出明确说明.导致后到的包仍然选择负载较大的节点参与传输,造成不必要的丢包,降低网络性能.
通过3.2的分析,本文发现在DropTail类中定义了指向PacketQueue的对象,通过该对象可以获取包队列中的队列长度及初始长度.原AOMDV路由协议的队列管理机制也采用了这一点.在原DropTail队列管理机制基础上,引进主动丢包思想,改进队列管理机制.
4.3.1 设定节点的队列接收阈值
由上所述,队列的初始长度手动设置为N.获取到的实时的队列长度为n.定义:如果获取的实时队列长度n小于0.9*N,即n∈0.9*N认为当前队列满足传输要求,可以参与传输.
4.3.2 跨层获取队列缓冲区长度
1)配置用于运行的tcl脚本文件,在tcl脚本中进行初始化.首先找到对应的路由层协议,set router [$n0 agent 255].其中255是端口号,agent 255代表是路由代理.其次初始化queue对象,set queue [$n0 set ifq_(0)].ifq_(0)中一般情况默认为0(单信道).最后,绑定路由和队列,$router attach-queue $queue.在路由层访问队列信息.
2)在QE_AOMDV头文件中加入“drop-tail.h”.在QE_AOMDV类中定义DropTail的指针queue_,以便操作DropTail的属性.
3)修改command函数,增加if(argc == 3)
{
if(strcmp(argv[1],"attach-queue")== 0){
queue_=(DropTail*)TclObject::lookup(argv[2]);
printf("I have attach to the queue! ");
return(TCL_OK);
}
}
通过tcl脚本建立的TclObject,建立实例过程cmd()激活影子对象的方法command(),并将定义的queue参数以向量形式传递给command()方法.
4)当节点收到一个包时,首先用queue_指针调用基类的limit()函数即queue_->limit()获取队列的初始长度.然后用指针queue_调用基类的length()函数即queue_->length()获取队列的实时长度,计算队列缓冲区长度的占有率.具体过程会在第5部分叙述.
4.3.3 基于DropTail的主动丢包的队列管理
当得到队列缓冲区长度的占有率后,与队列的接收阈值进行比较,如果达到接收阈值,表明队列当前的缓冲区长度较长,负载较大,链路压力较大,则丢弃数据包;反之,将该包放在队列尾部,等待发送.
本文提出的队列管理机制吸取了RED随机提前检测队列思想.在队列长度达到阈值90%*N时,提前检测出队列负载,不使其达到满负荷;阈值也不宜过小,使数据包丢弃数量过大,以免影响网络传输速度.和RED随机提前检测队列不同的是,本文改进后的队列管理机制只丢弃在接收阈值以外的数据包,不是随机丢弃,而且,不需要定时丢弃包,只在需要时进行丢包,既考虑到尽量减少丢失队列数据,又要防止队列充满后造成网络拥塞,是一个综合利弊因素后的一个择中选择,从而达到提高网络性能.
5.1.1 节点结构
在NS2中,节点和链路都占用适当的存储空间.一个单播节点由地址分类器和端口分类器组成.节点一般表示主机或路由器,有些节点会根据需要绑定相关代理和应用[14].
本文中,建立节点以set node($i)[$ns node]执行.实例过程node建立包含多个classifier对象的节点,该节点本身也是OTcl中单独的一个类.单播节点包含一个地址分类器(classifier_)和一个端口分类器(dmux_).这些分类器的功能是将包分派到相应的代理或链路中去.但要注意的是,Node_entry仅是一个标志变量,而不于classifier,是一个真实的对象.
5.1.2 节点设置
本文的节点参数如表1所示.
表1 节点参数表
Table 1 Node parameter table
参数类型参数值路由协议QE_AOMDV链路类型llMac类型Mac/802_11队列类型Queue/DropTail队列长度30天线类型Antenna/OmniAntenna无线信号传输模型Propagation/TwoRayGround物理类型Phy/WirelessPhy信道Channel/WirelessChannel拓扑new Topography路由跟踪ON代理跟踪ONMAC跟踪OFF场景跟踪OFF
节点初始化已经设置了仿真参数,所以节点要运行的路由协议队列长度等参数已经在仿真参数中获得.所有在node-config 命令执行之后创建的节点都拥有同样的性质,直到node-config命令中的一部分参数发生改变且执行之后.
NS是一个事件(event)驱动模拟器,利用一个名为Simulator的Tcl类来定义和控制整个模拟过程.
图1 事件调度示意图Fig.1 Event scheduling diagram
NS2实际仿真时,调度对象的Scheduler::run()函数不间断处理队列中事件,将队列中的其它事件派出并放入事件队列中,Scheduler::run()再调用Scheduler::dispatch()函数将一个事件从队列中弹出来,执行事件中Handler句柄处理函数handle()处理该事件.完成一个事件产生、排队、弹出被处理过程,值得注意的是,ns只支持单线程,故在任何时刻只有一个事件执行.图1为事件调度器的工作过程示意图.首先从事件队列中找到时间最先事件,用本身handler()函数处理完毕,在处理下一事件,不断重复执行最早事件,若有事件时间相同,按事件代码进入队列顺序执行.
NS2链路仿真包含部分网络层、链路层和物理层功能.仿真链路由DelayLink,Queue,TTL等多个组件(连接器子类)组合形成,如图2所示,它以队列缓存方式管理包到达、离开和丢弃,接收节点上层发来的数据,经过传播和发送延迟,将包发给下一节点或丢弃.
图2 链路中包传输示意图Fig.2 Packet transmission in the link
包在链路中的传输过程如下:来自节点的包先由Queue队列处理,队列不满则排队,否则丢弃.服务器判断链路Queue队列是否包发送,有包就根据相关包调度策略发给DelayLink对象.DelayLink对象计算所需要的传输延迟,将包传给调度器.调度器负责调度事件队列的调度,包在相应时间延迟后,发给TTL对象,调度器改变链路状态,链路便可处理下一个包.TTL收到包,将包的ttl值减1,判断ttl值若ttl大于0,则将包传给下一节点,否则将包丢弃.
而在实现上,LL类继承自LinkDelay类,声明Queue的指针ifq_,Queue的子类DropTail中又声明了PacketQueue类的指针q_,从而可以通过q_来获取到队列中的长度.
随着网络负荷的增加,吞吐量与网络负荷大致成正比递增[12].
Smax=
(1)
Smax表示当前节点的最大归一化吞吐量.E[P]表示链路层平均分组负荷.公式(1)表征802.11协议吞吐量Smax随着链路层平均分组负荷E[P]的增加而增加.假设节点处理数据的能力相同,节点负荷越大,节点越繁忙,网络出现拥塞的可能性越大[13].网络各层之间息息相关,彼此联系.每一层都留有各自的队列栈和缓存区.同一节点在同一时间既是数据包的承载者又是控制包的承载者.在同一时间维度内,共享该层的队列资源.网络层通过实时监控链路层的队列资源,动态调整本层数据包和控制包的发送策略,最有效的利用链路层资源.既不因为频繁发包使链路层应接不暇而丢包也不至于使链路层队列处于空闲状态等待时间过长而浪费资源[14].
因此,本算法引入节点的实时队列长度即当前节点的实时负荷提前检测.探讨在均衡网络负载状态下的网络性能.队列阈值设置0.9×N是根据随机提前检测度列原理,既考虑到少丢失队列数据,又要防止队列充满后造成网络拥塞,是一个综合利弊因素后的一个择中选择.队列数据充满90%以上的机会在一般网络流量下很小,所以包丢弃概率也很小.从实验结果证明看,在一定的网络流量下,该阈值取值效果最好.如果阈值取0.8N,数据包丢失过大造成网速减慢,流量减少.
QE_AOMDV路由协议主要修改了RREP和路由表的数据结构,新增“队列缓存区长度累加和”字段表征链路压力大小.
RREQ数据结构如表2所示.在正向转发RREQ包时,通过实时监测获取链路层队列资源情况,决定当前节点是否参与转发并设置延时.
表2 RREQ消息格式
Table 2 RREQ message format
类型JRGDU保留跳数目的节点IP地址目的节点序列号源节点IP地址源节点序列号路由请求识别码第一跳
RREP数据结构如表3所示.若当前节点即为目的节点或有到目的节点的有效路由项,需要将路径上节点的队列缓存区长度依次累加在一起,向源节点沿反向路径发送RREP应答消息.
表3 RREP消息格式
Table 3 RREP message format
类型RA保留前缀长度跳数目的节点IP地址目的节点序列号源节点IP地址寿命第一跳队列缓存长度累加和
路由表结构如表4所示.节点的缓存路由表中记录多条路径,当源节点收到多条路径时,选择队列缓存区长度累加和最小即链路压力最小的路径作为主路径进行数据的传输.
表4 路由表格式
Table 4 Routing table format
目的节点IP地址目的节点序列号广告跳数路由列表{(第一条路径下一跳,最后一跳,跳数,队列缓存区长度累加和),(第二条路径下一跳,最后一跳,跳数,队列缓存区长度累加和)…}寿命
AOMDV协议主要过程是:为了寻找到目的节点的路由,源节点广播RREQ 请求分组,节点路由表使用lasthop 和nexthop来唯一表示某条路径,通过该标志判断是否与其它路径相交.中间节点收到各邻居节点发送的RREQ分组,并检查RREQ分组的firsthop标识和节点的最后一跳列表,以此来判断该RREQ分组是否从源节点的不同邻居节点发送出来,即是否是一条新路径.中间节点收到来自上游的RREQ请求报文后,会向源节点发送RREP分组;而目的节点收到来自源节点的请求报文后,会马上向源节点发送RREP回复,RREP沿着正向路径逆向发送到源节点,当源节点收到第一个来自于目的节点的RREP后,正向路径便建立.把收到的第一条路径设为主路径[14,15].
如图3所示,原AOMDV多路径路由协议找到S-1-3-5-7-D,S-11-9-D,S2-4-6-8-10-D三条节点不相交路径.其中S-11-9-D为4跳路径,跳数最小,将此路径作为主路径,优先主路径传输.通过对AOMDV多路径路由协议的分析,当路由表中存在有效路由时,可以利用已有的路由传输数据,而当前路由中9号节点可能正在参与其他传输任务,路径负载较大,这就可能造成这条路径的拥堵,造成网络拥塞.难以保证数据的稳定传送,而此时适宜的空闲路径可能存在却没有得到有效利用,造成资源浪费.为解决以上问题,QE_AOMDV路由协议对AOMDV多径路由协议的路由发现过程提出以下两点改进,路由维护过程提出一点改进.
图3 路由寻路结构图Fig.3 Route maintenance structure
在路由发现过程中,中间节点收到来自邻居节点的RREQ请求报文,根据自身的负载状态来决定是否转发该报文或直接响应.如图4所示.
图4 中间节点收到RREQ的处理过程Fig.4 Process of receiving the RREQ at the intermediate node
在QE_AOMDV路由协议中,节点的缓存区初始队列长度为N,若实时的队列缓存区长度n达到90%*N并且已经收到过相同的RREQ包,那么该节点不适合继续参与传输,丢弃该报文.纵使有到目的节点的有效路由,也不继续参与传输.
i.在路由发现过程中,队列占有率为获取的节点实时队列长度和队列初始长度的百分比,用rationodei表示,如公式(2):
(2)
其中queuelhcurrent=queue_->length();
queuelhinitial=queue_->limit();
queue_->length()和queue_->limit()在3.3.2部分中已经提到,此不赘述.
ii.在路由发现过程中,报文的转发延时为节点缓存区实时队列长度的占比,用e2enodei表示.如公式(3):
e2enodei=rationodei
(3)
图5 中间节点收到RREP的处理过程Fig.5 Process of receiving the RREP at the intermediate node
如果中间节点通过实时监测队列获取到队列长度在90%*N以下,且没有到目的节点的有效路由,如图3所示,那么将RREQ请求报文封装好,延时转发给邻居节点.
通过获取节点实时的队列长度,计算队列占用率,中间节点处理好收到的RREQ包后,将队列占用率填充到RREP消息中,向源节点发送RREP路由应答.如图3所示,当目的节点收到RREQ消息后,依次累加路径上的队列占用率,用Totalratiopathi表示,如公式(4):
Totalratiopathi=∑rationodei
(4)
中间节点收到RREP后的处理过程如图5所示.当源节点收到第一条路径时,第一条路径是链路压力最小的路径.最小化延时的同时最优化了路径负载情况.路径 S-2-4-6-8-10-D的链路压力为0.8,S-1-3-5-7-D的链路压力为 1.2.如图3所示.因此,主路径被确定为 S-2-4-6-8-10-D,次路径为 S-1-3-5-7-D.
QE_AOMDV按需多路径路由协议和AOMDV路由协议的路由维护过程类似.不同的是在QE_AOMDV路由协议中,当一个节点在传输报文时,通过Hello包探测到链路受损,首先获取自身的缓存区队列长度m,如果当前长度m未达到队列初始长度N的90%,那么进行本地维修,如果达到90%,则向源节点发送RRER错误分组包,告诉路径上游前面的节点,和本节点相连链路出现错误.为了不再使用这些受损链路和节点,必要时由源节点开启新一轮路由发现过程.
图3中,Hello包探测到9号节点发生故障,9号节点的队列缓存区占有率为90%,超过阈值,由9号节点向上游节点沿反向路径发送RRER包,直至源节点,由源节点开启一轮新的寻路过程.如果9号节点的队列占比不超过阈值,那么将由11号节点发起一轮到目的节点的寻路过程.
本文采用NS-2仿真,仿真节点随机放置在600m×600m的矩形范围内,仿真时间为200s,在多节点仿真中,设置10个仿真场景,cbr发送速率恒为30kb/s,节点个数分别为14/24/34/44/54/64/74/84/94/104.将本文提出的改进方法和原AOMDV路由协议从端到端延时,网络吞吐量以及丢包率三方面进行对比.
图6 平均延时、吞吐量、丢包率随节点个数变化图Fig.6 Average delay,throughput,and packet loss rate as a function of the number of nodes
在多节点数目的仿真中,图6显示协议改进前后分别在平均延时,吞吐量、丢包率三方面的比较.其端到端延时总体降低9.1%.在较少的节点数目下,原有协议和QE_AOMDV路由协议在端到端延时不相上下.当节点数超过44时,随着节点数目的增多,节点的随机运动更复杂,碰撞几率更大,由于考虑了节点的负载情况,缓解了链路拥塞,QE_AOMDV路由协议的端到端延时始终小于AOMDV路由协议.
QE_AOMDV路由协议的吞吐量较原AOMDV路由协议提高20.1%.在不同的节点数目下,QE_AOMDV路由协议均呈现出较高的吞吐量,网络中拓扑环境较复杂时,原AOMDV因链路频繁断裂,无效路径的使用导致分组大范围丢弃,性能的差别变得更明显.
在网络中节点个数少于24之前,协议改进前后的丢包率持平.当节点数达到24后,两种协议的丢包率趋于平稳,且QE_AOMDV路由协议的丢包率始终小于AOMDV路由协议.改进的QE_AOMDV路由协议具有明显的优势.
在NS-2中仿真参数选择节点随机放置在600m×600m的矩形范围内,仿真时间为200s,在多速率仿真中,设置10个仿真场景,节点数恒为20,cbr发送速率分别为30(kb/s)/40(kb/s)/50(kb/s)/60(kb/s)/70(kb/s)/80(kb/s)/90(kb/s)/100(kb/s)/110(kb/s)/120(kb/s).
在多发送速率的仿真中,图7显示协议改进前后分别在平均延时,吞吐量、丢包率三方面的比较。协议改进后其延时降低9.0%。仿真开始时由于节点移动速度缓慢,网络拓扑相对变化小,节点链路出现断开机会偏小.两种协议时延较小.当cbr发送速率逐渐变大,队列的占用率逐渐增加,相应的转发延时渐增加,两种协议的端到端延时均呈现上升趋势.在不同的cbr发送速率下,QE_AOMDV路由协议有较高的吞吐量,吞吐量提高15.7%.随着发送速率的增加,节点的发送任务繁重,队列中待发送的数据包堆积,造成后到达的数据包因前向数据包未及时发送出去而被丢弃,造成数据包的意外丢失.QE_AOMDV路由协议将节点的队列缓存引入到路由发现中,原AODMV因链路频繁断裂,无效路径的使用导致分组大范围丢弃,性能的差别变得更加明显.改进后的QE_AOMDV路由协议具有明显的优势.QE_AOMDV多路径路由协议较AOMDV路由协议的丢包率总体降低9.0%.QE_AOMDV多路径路由协议由于将节点的队列缓存区长度加以考虑,使得部分数据包避免了使用缓存队列长度较长的节点参与传送任务,有效降低了丢包率.
图7 平均延时、吞吐量、丢包率随发送速率变化图Fig.7 Average delay,throughput,and packet loss rate as a function of transmission rate
本文结合原有AOMDV多路径路由协议,将队列缓存区长度引入QE_AOMDV多路径路由协议.通过考虑缓存区的队列空间,避免负载较重的节点参与传输,同时,根据负载情况进行延时转发和链路的修复.结果表明:改进后的QE_AOMDV多路径路由协议较原AOMDV协议相比,吞吐量整体提高,延时大大降低.QE_AOMDV多路径路由协议的性能优于原AOMDV路由协议.