引言
- 网络层的主要功能是将数据包从源机器路由到目标机器。在大多数是网络中,数据包需要多跳才能到达目的地。唯一一个值得指出的例外是广播网络,但即使在广播网络中,如果源机器和目标机器不在同一个网络段中时,路由仍然是一个问题。选择路由的算法以及这些算法所用的数据结构是网络层设计的最主要内容。
- 路由算法是网络层软件的一部分,它负责确定一个入境数据包应该被发送到哪一条输出线路上。如果网络内部使用了数据报,那么路由器必须针对每一个到达的数据包重新选择路径,因为自上一次选择了路径之后,最佳路径可能已经发生了改变。如果网络内部使用虚电路,那么只有当建立一条新的虚电路时,才需要做路由决策;伺候,数据包只要沿着已经建立的路径向前传递即可。后一种情形有时候称为会话路由,他被我在整个会话过程中,路径必须保持有效。
- 路由与转发的区分。路由即对使用哪一条路径作出决策,而转发是当一个数据包到达时该采取什么操作。可以把路由器想象成内部有两个进程。其中一个进程在每个数据包到达时对它进行处理,它在路由表中查找该数据包所对应的出境线路。这个进程称为转发进程;另一个进程负责生成和更新路由表,这正是路由算法发挥作用的地方。
- 无论是针对每个数据包独立选择路由,还是仅建立新连接时选择路径,路由算法必须满足某些特性:正确性、简单性、鲁棒性(健壮)、稳定性、公平性和有效性。正确性和简单性无需多加解释,对鲁棒性的要求似乎没有那么显而易见。一旦一个重要网络投入运行,它有可能需要连续运行数年而不能出现波及系统范围的失败。在此期间,将会有各种各样的硬件和软件发生故障。路由算法应该能够处理拓扑结构和流量方面的各种变化,而且不能要求所有主机都停止所有的工作。
- 稳定性对于路由算法来说也是一个重要目标。有一些路由算法无论运行多长时间从来都没有收到过一个固定路径的集合(收敛是所有路由器在最佳路径上取得一致的过程)。一个稳定算法能到达平衡(能采用最佳路径的选择通常会保持负载均衡),并且保持平衡状态。因此它应该迅速收敛,在路由算法达到平衡之前,通信可能无法进行。
- 公平性和有效性往往会相互矛盾。如图,假设在A和A次之间、B和B次以及C和C次之间有足够的流量使得水平链路达到饱和。为了使总流量达到最大,X和X次之间的流量应该被完全切断。全局效率和单个连接的公平性之间必须有一种折中的处理办法。
- 要找到折中办法,必须确定要优化什么性能指标。使数据包的平均延迟达到最小是有效发送流量的一种很明显的选择,但是使网络的总吞吐量最大化也是一个不错的选择。但这两个目标是相互冲突的,因为运行在任何一个接近容量的排队系统意味着排队延迟很长。作为一种折中,许多网络企图最小化一个数据包必须经过的跳数。两种选择趋向于减小延迟,同时减少每个数据包消耗的带宽数量,从而提高吞吐量。
- 路由算法可以分成两大类:非自适应算法和自适应算法。非自适应算法不会根据当前测量或者估计的流量和拓扑结构,来调整路由决策。相反,从I到J(对所有的I和J)所使用的路由选择是预先在离线情况下计算好,并在网络启动时被下载到路由器中的。这个过程有时也称为静态路由,因为它们无法响应故障,所以静态路由对于路由选择已经很清楚的场合非常有用。自适应算法则会改变它们的路由决策以便反映出拓扑结构的变化,通常也会反映流量的变化情况。这些动态路由算法在多个方面有所不同:获取信息的来源不同(例如来自本地、相邻路由器或者所有的路由器)、改变路径的时间不同(比如拓扑结构发生变化时,或者每隔多少时间随负载变化)以及用于路由算法的度量不同(比如距离、跳数或者估计的传输时间)。
- 在以后的章节中,将讨论不同的路由算法。算法除了从源端发送数据包到接收方外,还涉及传递模式。有时候路由的目标是把数据包发送到多个地址、全部地址或者一组地址中的一个。在这里描述的所有路由算法都基于拓扑结构进行路由决策;将基于流量水平做路由决策的可能性推迟到拥塞算法一章中讲解。
1、优化原则
- 在讨论具体算法之前,先不考虑网络拓扑结构和流量情况,而是给出最优路径的一般性描述。最优路径的一般陈述如下:如果路由器 J 在从路由器 I 到 K 的最优路径上,那么 J 到 K 的最优路径也必定遵循同样的路由。作为最优原则的一个直接结果,从所有的源到一个指定目标的路径的集合构成了一棵以目标节点为根的树,这样的树称为汇集树。如图b,图中的距离度量是跳数。所有路由算法的目标是为所有路由找到这样的汇集树,并根据汇集树来转发数据包。
- 汇集树并不是唯一的;有可能存在具有相同路径长度的其他汇集树。如果允许选择所有可能的路径(前提是遵守优化原则),则树就变成了更一般的结构,称为有向无环图(DAG)。DAG没有环路。由于汇集树没有换,所以每个数据包将在有限的跳数内完成传递。然而实际情况并非如此。在运行过程中,链路和路由器可能会故障,然后又恢复运行。所以,不同的路由器对当前拓扑结构的了解可能有所不同。不管如何,最优原则和汇集树为测量其他路由算法提供了一个基准。
2、最短路径算法
- 最短路径的一种测量路径长度的方法是跳数,另一种方法是以千米为单位的物理距离。然而,也可以使用平均延迟(最短路径就是最快路径)等方法。最优路径可能包含距离、带宽、平均流量、通信成本、平均延迟等因素,通过改变它们的权重,路由算法就可以根据任何一种标准或多种标准来计算“最短”路径。
- 一种算法(Dijkstra)是找出网络中的一个源节点到全部目标节点的最短路径。每一个节点都标出了(圆括号内)从源节点沿着已知的最佳路径到达本节点的距离。初始时,所有的路径都不知道,因此所有节点都被标记为无限远。算着算法的进行,陆续找到了最短路径,于是节点的标记发生变化,以便反映出更好的路径。每个标记可能是暂时的,也可能是永久的。初始时,所有的标记都是暂时的,当发现一个标记代表了从源节点到该节点的最短可能路径,该标记就变成永久。(图,从A到D最短路径计算的前6个步骤)
- 为了说明标记算法的过程,先看图a中的加权无向图,这里是权值代表了一种度量,比如说距离。我们现在要找出从A到D的最短路径。开始时将节点A标记为永久,然后依次检查每一个与A相邻的节点,并且用它们与A之间的距离重新进行标记。为了可以重构出最终路径,每当一个节点被重新标记时,也要标记出这次探测动作的出发节点(即前一个节点)。在检查了每一个与A相邻的节点之后,我们检查整个图中全部具有暂时性标记的节点,并且使得其中具有最小标记的那个节点称为永久性的,如图b所示,这个节点就变成新的工作节点。下面给出这个算法的程序描述。全部变量n和dist(distance)描述了图,在shortest_path被调用之前对这两个变量进行初始化。这段程序与前面描述的算法之间唯一的区别是,从终结节点 t 开始计算最短路径,而不是从源节点 s 开始。
#define MAX_NODES 1024 /* maximum number of nodes */
#define INFINITY 1000000000 /* a number larger than every maximum path */
int n, dist[MAX_NODES][MAX_NODES]; /* dist[i][j] is the distance from i to j */
void shortest_path(