电子常识
如果您已经阅读过博闻网中的路由器工作原理一文,您会了解到路由器的作用是管理网络流量和找到发送分组数据包的最佳路由。但是您是否想过路由器是怎么做到这一点的?路由器需要一些网络状态的信息来决定如何发送分组数据包以及发往哪里。但是它是怎样收集这些信息的?
在本篇博闻网文章中,我们将带您详细了解路由器需要哪些信息来决定往哪发送分组数据包。
路由器使用路由算法来找到到达目的地的最佳路由。当我们说“最佳路由”时,我们考虑的参数包括诸如跳跃数(分组数据包在网络中从一个路由器或中间节点到另外的节点的行程)、延时以及分组数据包传输通信耗时。
关于路由器如何收集网络的结构信息以及对之进行分析来确定最佳路由,我们有两种主要的路由算法:总体式路由算法和分散式路由算法。采用分散式路由算法时,每个路由器只有与它直接相连的路由器的信息——而没有网络中的每个路由器的信息。这些算法也被称为DV(距离向量)算法。采用总体式路由算法时,每个路由器都拥有网络中所有其他路由器的全部信息以及网络的流量状态。这些算法也被称为LS(链路状态)算法。我们将在下一节讨论LS算法。
采用LS算法时,每个路由器必须遵循以下步骤:
Dijkstra算法执行下列步骤:
这些步骤的流程图如下:
|
在下一页中我们将使用这个算法具体分析一个示例。
我们想找到A与E(下图)之间的最佳路由。可以看到A与E之间有六条可能路径(ABE、ACE、ABDE、ACDE、ABDCE、ACDBE),很明显ABDE是最佳路由,因为它的权值最小。但是实际情况并非总是如此简单,有很多复杂的情形需要使用算法来找到最佳路由。
|
|
|
|
我们已经到达了终点!现在,我们需要确定路由。E的前序节点是D,D的前序节点是B,B的前序节点是A。所以最佳路由是ABDE。在这个案例中,权值和为4(1+2+1)。
虽然这个算法工作良好,但是它非常复杂,以致于路由器需要花费大量时间进行处理,网络的性能因此下降了。同样,如果一个路由器将错误的信息发送给其他路由器,那么所有的路由决定都将是无效的。为了更好的理解这个算法,下面给出由C语言编写的源代码:
#define MAX_NODES 1024 /*最大节点数 */ #define INFINITY 1000000000 /*比所有最大路径都大的数 */ int n,dist[MAX_NODES][MAX_NODES]; /*dist[I][j] 是从 i 到 j 的距离*/ void shortest_path(int s,int t,int path[ ]) {struct state { /*当前计算的路径 */ int predecessor ; /*前序节点 */ int length /*从源节点到当前节点的长度*/ enum {permanent, tentative} label /*标号状态*/ }state[MAX_NODES]; int I, k, min; struct state * p; for (p=andstate[0];p < andstate[n];p++){ /*初始化状态*/ p->predecessor=-1 p->length=INFINITY p->label=tentative; } state[t].length=0; state[t].label=permanent ; k=t ; /* k 是初始工作节点 */ do{ /*是从 k 开始的一条更好路径么?*/ for I=0; I < n; I++) /*图有 n 个节点 */ if (dist[k][I] !=0 andand state[I].label==tentative){ if (state[k].length+dist[k][I] < state[I].length){ state[I].predecessor=k; state[I].length=state[k].length + dist[k][I] } } /*找到具有最小权值的暂时性节点。*/ k=0;min=INFINITY; for (I=0;I < n;I++) if(state[I].label==tentative andand state[I].length < min)=state[I].length; k=I; } state[k].label=permanent }while (k!=s); /*将路径复制到输出数组*/ I=0;k=0 Do{path[I++]=k;k=state[k].predecessor;} while (k > =0); } |
DV算法也被称为Bellman-Ford路由算法和Ford-Fulkerson路由算法。在这些算法中,每个路由器都有一个路由表,用来表示到任何目的地的最佳路由。一个典型的路由器J的网络图以及路由表如下所示。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如表格所示,如果路由器J想发送分组数据包到路由器D,它应该将分组数据包先发送到路由器H。分组数据包到达路由器H后,它将检查自己的路由表来决定怎样将分组数据包发送到路由器D。
在DV算法中,每个路由器遵循以下步骤:
DV算法的一个最主要的问题是“无穷计数”。让我们通过一个例子来研究一下这个问题:
假设一个网络图如下所示。如图所示,A与网络的其他部分只有一条链路。所有节点的路由表以及网络图如下所示:
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
网络图和路由表
现在假设A 、 B之间的链路被剪断了。在这个时候,B修正了自己的路由表。经过一段时间后,路由器交换它们的路由表,因此B接收到了C的路由表。因为C不知道A 、B之间的链路上发生了什么事,所以它说它有一条权值为2的到A的链路(从C到B权值为1,从B到A权值为1——它不知道B已经没有到A的链路了)。B接收到路由表之后认为有另外一条链路从C到A,所以它修正了自己的路由表,即将无穷大更改为3(C认为,B到C权值为1,C到A权值为2)。路由器然后再一次交换它们的路由表。当C接收到B的路由表后,它发现B到A的链路权值从1更改为3,所以C更新了它的路由表,即将它到A的链路权值更改为4(根据B的描述,C到B权值为1,B到A权值为3)。
这个循环过程到最后,所有的节点发现到A的链路权值变成无穷大。这个情形如下表所示。因此,专家称DV算法具有低收敛率。
|
|
| |
链接剪断之后到A的权值之和 |
|
|
|
第一次更新后到B的权值之和 |
|
|
|
第二次更新后到A的权值之和 |
|
|
|
第三次更新后到A的权值之和 |
|
|
|
第四次更新后到A的权值之和 |
|
|
|
第五次更新后到A的权值之和 |
|
|
|
第n次更新后到A的权值之和 |
|
|
|
|
|
|
“无穷计数”问题
解决这个问题的一种方法是,路由器只发送信息给相邻路由器,且该相邻路由器不是通往目的地的唯一链接。比如在这个例子中,C就不应该发送任何关于A的信息给B,因为B是通往A的唯一路径。
可以看到,在LS和DV算法中,每个路由器都需要保存其他路由器的一些信息。随着网络规模的扩大,网络中的路由器也将增加。因此,路由表的规模也将增大,从而使路由器不能有效地处理网络流量。使用分级路由可以解决这个问题。让我们通过一个例子来说明一下。
我们使用DV算法来查找节点间的最佳路由。在下述情形中,网络中的每个节点保存了一个有17个记录的路由表。下面是A的一个典型网络图和路由表。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在分级路由中,路由器被分成很多组,称为区域。每个路由器都只有自己所在区域路由器的信息,而没有其他区域路由器的信息。所以在其路由表中,路由器只需要存储其他每个区域的一条记录。在这个例子中,我们将网络分为5个区域(如下图)。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果A想发送分组数据包到在区域2中的一个路由器(D、E、F或G),它就将分组数据包先发送到B,依此类推。可以看到,在这种类型的路由中,可以对路由表进行概括,因此网络效率提高了。上面的例子描述了一个两级的分级路由。同样我们也可以采用三级或者四级的分级路由。
在一个三级的分级路由中,网络被分为很多簇。每个簇由很多个区域组成,每个区域包含很多个路由器。分级路由广泛应用于互联网路由中,并且使用了多种路由协议。
全部0条评论
快来发表一下你的评论吧 !