路由模拟项目介绍

链路状态协议(Link-state routing protocol)和距离向量路由协议(Distance-vector routing protocol)是分组交换(Packet switching)网络中最主要的两种路由协议。本项目的模拟路由器实现了LS路由算法、LS广播洪泛、DV路由算法,以及防止DV路由环路和无穷计数问题的策略。此外还实现了完整的前后端以便研究者通过UI界面自定义网络拓扑、控制路由器、查看路由器信息和日志。

链路状态算法(LS)

LS算法要求网络中每个节点都收集完整的网络信息,以邻接表的形式存储整个网络的拓扑结构和所有链路的费用,然后根据这个图来运行路由选择算法(在这里我们选择Dijkstra算法),计算出从本节点到网络中所有其他节点的最低费用路径。

LS广播

为了让每个节点都知道整个网络的拓扑结构和所有链路费用,每个节点都要将自己直连的链路信息广播给网络中的所有节点(LS广播)。要广播的信息包括自己的邻居有哪些、到达它们的链路开销分别是多少。

为了更新它本身存储的网络拓扑图,在接收到其他节点的LS广播时,要根据广播中的链路信息更新自己的邻接表。

同时,在接收到其他节点的LS广播时,要将它转发给自己的所有邻居,从而这个LS广播能散播到整个网络。为了避免广播风暴(广播包在网络中无休止地传播,导致网络瘫痪),每个路由器要辨别接收到的LS广播包是不是已经接收过。这可以通过一个广播包中的序列号字段来做到。每台ls路由器,每次广播使用一个递增的序列号,如果多次收到来自同一台路由器且序号相同的广播,则不更新邻接表,也不转发给邻居,防止广播风暴。

迪杰斯特拉算法(Dijkstra's algorithm)

Dijkstra算法能够计算出图中所有节点到某个节点的最短路径。对于一个图和一个给定的原点,Dijkstra算法不断选择一个距离源点最近且尚未扩展的节点w来扩展,并更新w的邻居节点到原点的距离。最终,所有被扩展的节点就是从原点可以到达的节点,它们被扩展时到原点的距离就是最终的最短距离。

什么时候触发Dijkstra算法计算出新的路由表

Dijkstra算法的输入就是节点维护的邻接表,因此只要邻接表有更新,就要触发Dijkstra算法计算出新的路由表。

那么邻接表什么时候会更新呢?有2种情况:

本节点的直连链路发生变化,要更新邻接表中对应的链路。

接收到新的LS广播,要根据LS广播中的信息更新邻接表。

距离向量算法(DV)

DV算法不需要全局网络信息。每个节点只从直连邻居接收路由通告,执行DV计算,然后将计算结果分发给直连邻居。重复这个过程,直到每个节点的DV计算结果都与上一次的DV计算结果相同,此时网络中不再有路由通告,算法终止。

DV算法

DV算法的思想相对比较简单:邻居能到达的节点,我经过这个邻居也能到达,并且我去目标节点的费用 = 我到邻居的费用 + 邻居到目标节点的费用。一个节点的DV存储的就是这个节点能到达哪些节点、费用分别是多少。

DV算法的输入是所有邻居的DV和自己的直连链路信息,输出是自己的DV(也就是路由表)。如果输出的DV与上次输出的不同,也就是自己的DV发生了变化,那么要将自己的DV通告给所有邻居。

有几点需要注意:

为了保证DV算法的自我终止(网络中不再有DV通告,也不再运行DV算法),仅仅当DV发生变化时才通告给邻居。

DV的计算完全不依赖于自己上次计算得到的DV(也就是自己当前的路由表)。

路由环路和无穷计数问题

由于DV算法没有全局网络信息,DV算法中可能会出现路由环路和无穷计数的问题。

The Bellman–Ford algorithm does not prevent routing loops from happening and suffers from the count-to-infinity problem. The core of the count-to-infinity problem is that if A tells B that it has a path somewhere, there is no way for B to know if the path has B as a part of it.

如果A告诉B:A能到达C。由于B没有全局网络信息,它无法知道自己是否已经处于从A到C的路径上。

https://en.wikipedia.org/wiki...

路由毒化:如果一个节点A发现节点B变为不可达,那么A就要毒化从A到B的路由(也就是将去往B节点的费用设置为无穷),并且将毒化信息传播给所有邻居。如果A的某个邻居C原本是经过A去往B的,那么C去往B的路由也被毒化,同时C向它的邻居也传播毒化信息,以此类推。这个过程就像是毒性的传播一样。最终,通过A-B链路去往B的那些节点都会被毒化,从而没有路由会再利用这个失效的A-B链路。

横向分割:如果节点A是通过B去往C的,那么A不告诉B:“我能到达C”。从而避免再B-C链路失效以后,B选择通过A来到达C。这个方法只能避免2个节点组成的路由环路。

Holddown:在去往C的路由被毒化的一段时间内,不再接受邻居通告的任何去往C节点的路由,因为这个路由可能也使用了失效的链路,只不过尚未被毒化。

毒性逆转:一般与横向分割和Holddown一起使用。如果C接受到A的毒化路由以后也中毒,那么C要把自己毒化后的路由发给A。从而A能更新邻居的DV使其不包含失效的路由。

设计文档

路由器设计

我们的路由器实例是运行在同一台机器上的,它们之间通过UDP进行通信。

路由器类的主要成员

prot是本路由器的监听的端口。路由器与路由器之间通过UDP socket进行通信(交换路由信息、发送普通消息报文)。由于prot肯定是全局唯一的,因此我们也将它用作路由器的标识符。

neighbors存储直连的邻居信息,包括邻居的port、链路的cost。为了加速查询,它的数据结构是一个以邻居port为key的Map。

它是网络拓扑变化的根本来源,它的更新会触发ls算法或dv算法的执行、ls广播或dv通告。

当修改网络拓扑时,修改它,网络拓扑的变化信息就能扩散到整个网络

adjacencyList、DVs的更新从根本上来说都来自于它的更新。

算法为ls时,将它广播到整个网络

算法为dv时,在计算自己的dv(也就是路由表)的时候需要用到它

routeTable是路由器的路由表。用来转发数据包。

它是ls或dv的计算结果,不要直接修改routeTable,而是修改数据来源(也就是neighbors或adjacencyList或neighborsDVs),然后触发路由算法,从而更新路由表。

道理类似于:我们不应该直接修改编译器的输出代码,而应该去修改输入编译器的源代码,然后重新编译。从而输出会相应地改变。

adjacencyList只在链路算法为ls的时候使用,它是存储了整个网络信息的邻接表。当接收到ls广播,或自己的直连链路变化(也就是neighbors变化),都要触发它的更新。

使用邻接链表运行Dijkstra算法时,要忽略那些单向的链路(也就是说,如果A的邻居中有B,但B的邻居中没有A,那么不算这条链路)。

Dijkstra算法的输出只包括从本节点可达的节点,利用这一点,可以定期将adjacencyList中已经不可达的节点的邻居表删除。

neighborsDVs(在设计图中的DVs)维护了所有邻居发来的DV通告。为了加速存取,它的数据结构是以邻居port为key的Map。

前后端设计

前端是用Angular5和typescript制作的简单UI,运行在浏览器中;后端是用Node.js写的服务器,模拟路由是完全在后端进行的。前端与后端之间通过WebSocket而不是HTTP来通信,以便后端能主动、实时地发送信息给前端显示。

前端主要包含4个部分:

BackendService负责通过WebSocket与后端进行通信;

NetworkService负责根据后端发来的消息来绘制UI,并响应用户在UI上的操作;

PanelComponent负责展示用户选中的路由器或链路的信息,并提供一些针对选中对象的操作。

Chrome(或其他浏览器)控制台。后端运行的路由器实例产生的日志将通过Websocket连接发送到前端,前端将日志打印在控制台。用户如果想要查看路由器的运行过程需要打开控制台再刷新页面。由于浏览器的控制台自带filter功能,用户可以选择只查看某个路由器发出的日志、某种操作发出的日志。

后端主要包含3个文件:

server.ts负责监听WebSocket端口、调用RouterController来操作路由器和链路;

RouterController.ts负责维护并操作网络中所有的路由器实例,比如连接路由器、关闭路由器、改变路由器之间的链路,它提供操作网络的接口给server.ts;

router.ts定义了路由器类,其实现了ls算法和dv算法,并提供操作单个路由器的接口给RouterController.ts。

配置和运行

先安装node.js。

克隆这个仓库,切换到dev分支。

运行后端程序。命令行进入server文件夹,依次执行“npm install”来安装后端依赖,“npm run build”来编译后端项目(此命令会一直监视文件变化并重新编译)。再打开一个命令行窗口并进入server文件夹,执行“npm run serve”来运行后端项目,看到server is listening on port 8999表示服务端成功运行。

运行前端程序。然后从命令行进入client文件夹,依次执行“npm install”和“ng serve”。看到已下信息表示客户端网页已经可以可以访问。

打开浏览器,访问“http://localhost:4200/”即可。如果还想要查看路由器日志可以打开浏览器控制台并刷新页面。如果出现“socket发生错误,点击确定刷新页面”弹窗,表示客户端无法通过WebSocket连接到后端,请确保后端正在运行。

默认情况下,运行的是dv算法的路由器。如果要换成ls算法,修改“router.ts”的这一行:

将“dv”改为“ls”(“npm run build”命令行窗口会监测到变化并重新编译)。然后重新执行“npm run serve”来运行后端项目。

运行结果

左上角的操作栏可以添加、删除路由器和链路。点击路由器或链路,会在右边栏显示它的信息和一些操作。路由日志显示在浏览器控制台中,如果想要只查看某个路由器的日志或某个操作的日志,只需要在控制带的Filter输入框中输入过滤字符串,比如“9014log”,或“route table has changed”。

可以通过这个项目来自定义网络拓扑、操作网络拓扑,并观察路由表的变化。具体的例子在视频中展示。

阅读资料

c语言模拟洪泛路由算法,[Angular, TypeScript, 路由算法] 模拟IP层路由协议,实现LS算法、洪泛算法、DV算法、路由毒化...相关推荐

  1. dv路由算法c语言实现,路由协议之DV算法

    #include #define ROUTER_OF_NUMBER 100 //网络中路由的最大数目 #define MaxExp 10000 //假设为此路由费用为无穷大 int RouterNum ...

  2. C#进程调度的模拟实现:模拟先来先服务调度算法、短作业优先调度算法和优先级调度算法(考虑非抢占式和抢占式),进行算法评价,输出调度结果和算法评价指标。

    没什么水平,希望能帮到你 环境:visual studio 2019 附带工程资源:C#进程调度的模拟实现附带资源-C#文档类资源-CSDN下载 先来先服务的调度算法:是一种非抢占式的算法,先来先服务 ...

  3. 【校招常见算法】暴力法、模拟

    目录 前言 什么是暴力法? 什么是模拟? 例题 小结 前言   [校招常见算法]暴力法.模拟,是最基础的算法,我们后面要学习的算法很多时候都要先从暴力法.模拟开始去思考,最后才能想出比较优的解法. 视 ...

  4. 浙江万里学院c语言题库答案,浙江万里学院单片机原理及应用模拟试卷八.doc

    浙江万里学院单片机原理及应用模拟试卷八 浙江万里学院单片机原理及应用模拟试卷八 一.填空(每空1分,共30分) 1.把计算机的CPU. 和多种接口集成在一块芯片上,称为微处理器,也叫微控制器,简称 . ...

  5. 《IP路由协议疑难解析》一1.3 动态路由

    本节书摘来自异步社区<IP路由协议疑难解析>一书中的第1章,第1.3节,作者 [美]Zaheer Aziz, CCIE #4127 , Johnson Liu, CCIE #2637 , ...

  6. Interview:算法岗位面试—上海某科技公司算法岗位(偏AI算法,国企)技术面试之BN层的认知、BP的推导、GD优化的几种改进等

    Interview:算法岗位面试-上海某科技公司算法岗位(偏AI算法,国企)技术面试之BN层的认知.BP的推导.GD优化的几种改进等 导读:关于神经网络,问的比较深,因为博主做过总结,所以用自己的语言 ...

  7. 编写算法判别给定二叉树是否为完全二叉树_推荐一位实力超强的平安前端算法大佬:瓶子君...

    今天给大家推荐一位平安大佬:前端瓶子君,一个专注于前端开发的小瓶子,五年大厂开发经验,掘金优秀作者. 「前端进阶算法」系列是她4月初发起的活动,从 0 到 1 构建完整的前端数据结构与算法体系.这是一 ...

  8. LeetCode琅琊榜第十六层-Z字型变换(直接构造法 + 周期性算法)

    LeetCode6.Z字形变换 难度:中等 往期力扣与博主空间 题目链接  目录 官方解法1-构造Z字型数组模拟 案例分析 规律探索 原因: 代码实现 代码分析: 问题 官方解法二-压缩上述二维数组 ...

  9. 推荐系统[八]算法实践总结V0:淘宝逛逛and阿里飞猪个性化推荐:召回算法实践总结【冷启动召回、复购召回、用户行为召回等算法实战】

    搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排).系统架构.常见问题.算法项目实战总结.技术细节以及项目实战(含码源) 专栏详细介绍:搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排 ...

  10. Web框架之Django_03 路由层了解(路有层 无名分组、有名分组、反向解析、路由分发 视图层 JsonResponse,FBV、CBV、文件上传)

    阅读目录 一.路由层:(Django的路由系统) 二.伪静态网页和虚拟环境: 三.FBV与CBV.JsonResponse.文件上传 一.路由层:(Django的路由系统) URL配置(Django项 ...

最新文章

  1. SAP HUM 如何把HU号码与Outbound Delivery 解除Assignment?
  2. 理解CMS GC日志
  3. 教学案例 计算机,宁夏计算机教学案例
  4. z变换判断稳定性和因果性_图像处理的仿射变换与透视变换
  5. 9月20日 DNS总结
  6. Column name pattern can not be NULL or empty.
  7. MVC+LINQToSQL的Repository模式之(二)数据基类
  8. 奇安信代码安全实验室帮助微软修复高危漏洞,获官方致谢
  9. php中mysql数据库集群,MySQL集群
  10. iOS底层探索之对象的本质和类的关联特性initIsa(上)
  11. SqlServer复制表结构:从另一张表中获取某些字段和类型并添加到一张已经存在的表中...
  12. Lucene.net试用
  13. 安装Mercurial进行版本管理
  14. Oracle数据库多语言文字存储解决方案
  15. 密码学的数学基础2-同余
  16. 计算机操作系统32位,电脑操作系统中32位和64位到底有哪些区别
  17. git中fatal: Authentication failed for 的问题
  18. 2020家用千兆路由器哪款好_什么路由器比较好(2020年最好千兆路由器)
  19. 64位操作系统注册ocx控件失败,提示:模块加载失败请确保该二进制存储在指定路径中。
  20. Unity相机漫游脚本

热门文章

  1. 2022 年最新博客专家申请流程
  2. 用python.turtle画中国地图
  3. Android加固与脱壳分析
  4. 英语读音(二) / English Pronounciation
  5. 2019中国大学排名
  6. 云计算的特点,主要有哪些?
  7. 计算机教学楼起名,给教学楼起名字(富有诗意教学楼名字)
  8. 软件工程师考试报名须知
  9. SQL Server2019安装步骤(超详细 附下载链接)
  10. 数据库上机实验八(视图)