前言:
好久不见,有段时间没有写文章了,本篇文章,由Blue我带大家来复现rip协议。我们以
b站湖南教师匠所讲rip的视频中的例子为我这篇文章所模拟的路由路径
如图:
模拟路径
视频:http://【深入浅出计算机网络 - 4.4.3 路由信息协议RIP】https://www.bilibili.com/video/BV1ST411K7nK?vd_source=bb412cc25ca27e171f8e17085daad038
Rip协议工作原理:
- 1、rip协议要求网络中每个路由器都要维护从它自己到其他每一个目的网络的距离记录。
- 2、rip认为好的路由就是它通过的网路数目少的,及“距离最短”。
- 3、rip最多允许一条路径包括15个网络。距离为16时相当于不可达。
- 4、仅和相邻路由器交换信息,这里的信息指的是所有网络的最短距离,以及到每个网络应经过的下一跳路由
- 5、按固定时间间隔交换路由信息
代码实现:
第一步:搭建项目
注意:我搭建的是boot项目,实际我这个复现,并没使用boot,所以你也可以不搭建boot
项目结构:
第二步:定义路由表中的关键列(目的网络,距离,下一跳)
RouterTable:
package com.example.Kclass;/*** 路由表:* 1、目的网络* 2、距离* 3、下一跳路由器*/
public class RouterTable implements Cloneable{private Integer AimNet;private Integer distance;private String NextRouter;public RouterTable() {}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public RouterTable(Integer AimNet, Integer distance, String NextRouter) {this.AimNet = AimNet;this.distance = distance;this.NextRouter = NextRouter;}/*** 获取* @return AimNet*/public Integer getAimNet() {return AimNet;}/*** 设置* @param AimNet*/public void setAimNet(Integer AimNet) {this.AimNet = AimNet;}/*** 获取* @return distance*/public Integer getDistance() {return distance;}/*** 设置* @param distance*/public void setDistance(Integer distance) {this.distance = distance;}/*** 获取* @return NextRouter*/public String getNextRouter() {return NextRouter;}/*** 设置* @param NextRouter*/public void setNextRouter(String NextRouter) {this.NextRouter = NextRouter;}public String toString() {return "RouterTable{AimNet = " + AimNet + ", distance = " + distance + ", NextRouter = " + NextRouter + "}";}
}
第三步:定义路由器
Router:
package com.example.Kclass;import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;/*** 路由器的模板类**/
public class Router {private int id;List<RouterTable> routerTables = new ArrayList<>();public void setId(int id) {this.id = id;}public int getId() {return id;}public String find(int aimid){String sc ="完成";for (RouterTable e : routerTables){if(e.getAimNet()==aimid){System.out.println("需要经过的路由器:"+this.id);System.out.println("");if(e.getNextRouter().equals("直连")){return sc;}else {return e.getNextRouter();}}}return sc;}//添加操作public void add(RouterTable routerTable){int count=0;//存在相同的目的网络则不添加for (RouterTable e1 : routerTables){if(e1.getAimNet().equals(routerTable.getAimNet())){//不添加return;}}routerTables.add(routerTable);}//更新操作public void update(List<RouterTable> r1){/*** 遍历,看这个路由表满足这几种可能不?* 1、没有就插入* 2、有,如果下一跳相同则直接更新* 3、有,下一跳不同,且r1的距离小于自身的,将下一跳换成r1的下一跳,并且更新* 4、有,下一跳不同,且r1的距离大于自身的,不管舍弃*///遍历for (int i=0;i<r1.size();i++){for (int j=0;j<routerTables.size();j++){//是否存在相同的目的网络if(r1.get(i).getAimNet().equals(routerTables.get(j).getAimNet())){//是否下一跳也相同if(r1.get(i).getNextRouter().equals(routerTables.get(j).getNextRouter())){//相同,直接更新routerTables.get(j).setDistance(r1.get(i).getDistance());break;}else {//不同,判断距离if(routerTables.get(j).getDistance()>r1.get(i).getDistance()){routerTables.get(j).setDistance(r1.get(i).getDistance());break;}else {break;}}}if(j==routerTables.size()-1){routerTables.add(r1.get(i));}}}}//打印其路由表public void prints(){System.out.println(id+"的路由表为:");System.out.println("---目的网络---距离-----下一跳路由-----");for(RouterTable e : routerTables){System.out.println("---"+e.getAimNet()+"-----"+e.getDistance()+"------"+e.getNextRouter());System.out.println("");}}public List<RouterTable> deepCopyRouterTables() {List<RouterTable> copiedList = new ArrayList<>(routerTables.size());for (RouterTable routerTable : routerTables) {try {copiedList.add((RouterTable) routerTable.clone()); // 深拷贝} catch (CloneNotSupportedException e) {e.printStackTrace(); // 处理异常}}return copiedList;}
}
第四步:定义网络
NetWork:
package com.example.Kclass;public class NetWork {private int id;public NetWork() {}public NetWork(int id) {this.id = id;}/*** 获取* @return id*/public int getId() {return id;}/*** 设置* @param id*/public void setId(int id) {this.id = id;}public String toString() {return "NetWork{id = " + id + "}";}
}
第五步:定义User
package com.example.Kclass;public class User {private int id ;private int Routid;public User() {}public User(int id, int Routid) {this.id = id;this.Routid = Routid;}/*** 获取* @return id*/public int getId() {return id;}/*** 设置* @param id*/public void setId(int id) {this.id = id;}/*** 获取* @return Routid*/public int getRoutid() {return Routid;}/*** 设置* @param Routid*/public void setRoutid(int Routid) {this.Routid = Routid;}public String toString() {return "User{id = " + id + ", Routid = " + Routid + "}";}
}
第六步:Ts代码
package com.example.test;import com.example.Kclass.NetWork;
import com.example.Kclass.Router;
import com.example.Kclass.RouterTable;
import com.example.Kclass.User;import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;/*** 1、四个网络* 2、四个路由器* 3、创建图(利用图来表示链接)* 4、该类目的是弄好路由器的交换表*/
public class Ts {public static void main(String[] args) {List<NetWork> netWorks =new ArrayList<>();List<Router> routers =new ArrayList<>();rip(netWorks,routers);//用户界面User user =new User(1,1);MainPannel(routers,user);}public static void ppt(List<Router> routers){for (Router e:routers){e.prints();}}public static void MainPannel(List<Router> routers,User user){while (true){int a;System.out.println("选项1:打印所有路由表");System.out.println("选项2:用户传输信息");System.out.println("选项3:退出");Scanner s =new Scanner(System.in);System.out.println("请输入选项:");a=s.nextInt();switch (a){case 1:ppt(routers);break;case 2:userprint(routers,user);break;case 3:return;}}}public static void userprint(List<Router> routers, User user){System.out.println("请输入需要传送到的网络");int a;Scanner sc = new Scanner(System.in);a=sc.nextInt();int t=a;//知道自己从那个路由出发int routid= user.getRoutid();Router router = routers.get(routid - 1);boolean flage =true;while (flage){String s = router.find(t);if(s.equals("完成")){System.out.println("完成");return;}a = Integer.parseInt(s);router=routers.get(a-1);}}public static void rip( List<NetWork> netWorks, List<Router> routers) {//生成四个网络//令四个网络为1,2,3,4for (int i=1;i<=4;i++){NetWork e =new NetWork();e.setId(i);netWorks.add(e);}//生成四个路由器//令四个路由器为5,6,7,8for (int i=5;i<=8;i++){Router e =new Router();e.setId(i-4);routers.add(e);}//生成线路int[][] arry=CreateImage();//rip基本原理规定:路由器刚开始工作只知道自己到直连网络的距离为1//根据线路初始化initialization(routers,arry);//打印初始化后的每个路由器的路由表
// System.out.println("--------------------路由表的初始化-----------------------");
// for (Router e:routers){
// e.prints();
// }//根据rip基本原理每个路由器仅和相邻路由器周期性地交换并更新路由信息find(routers,arry);
// System.out.println("--------------------路由表的最终-----------------------");
// for (Router e:routers){
// e.prints();
// }}public static int[][] CreateImage(){int[][] arry={{0,0,0,0,1,1,0,0},//N1所对应的行,0{0,0,0,0,1,0,1,0},//N2所对应的行,1{0,0,0,0,0,0,1,1},//N3所对应的行,2{0,0,0,0,0,1,1,1},//N4所对应的行,3{1,1,0,0,0,0,0,0},//R1所对应的行,4{1,0,0,1,0,0,0,0},//R2所对应的行,5{0,1,1,1,0,0,0,0},//R3所对应的行,6{0,0,1,1,0,0,0,0} //R4所对应的行,7};return arry;}//初始化public static void initialization(List<Router> routers,int[][] arry){for (int i=4;i<=7;i++){for (int j=0;j<4;j++){if(arry[i][j]==0){continue;}if(arry[i][j]==1){routers.get(i-4).add(new RouterTable(j+1,1,"直连"));}}}}//用于更新public static void exchenge(Router e1,Router e2){//先让e1去更新e2// 深拷贝List<RouterTable> Copye2 = e2.deepCopyRouterTables();String next=e2.getId()+"";//根据rip协议,让其距离加1,下一跳变为e1for (RouterTable table :Copye2){table.setDistance(table.getDistance()+1);table.setNextRouter(next);}e1.update(Copye2);//e2去更新e1String next2=e1.getId()+"";//深拷贝List<RouterTable> copy1 = e1.deepCopyRouterTables();//根据rip协议,让其距离加1,下一跳变为e2for (RouterTable table :copy1){table.setDistance(table.getDistance()+1);table.setNextRouter(next2);}e2.update(copy1);}//用于遍历数组,查找相同路由器public static void find(List<Router> routers,int[][] arry){//双指针遍历int A=0;int B=0;for (int i=0;i<4;i++){boolean flage=true;//优化操作if(flage) {for (int j = 4; j < 8; j++) {if (arry[i][j] == 1) {A = j;//找到第一个1,然后继续下去找B=j;flage=false;break;}}}for (int j=B+1;j<8;j++){if (arry[i][j]==1){//执行更新exchenge(routers.get(A-4),routers.get(j-4));//判断是否还有可能存在相邻if(j<7){int s=B;B=j;for (int w=B+1;w<8;w++){if(arry[i][w]==1){exchenge(routers.get(A-4),routers.get(w-4));exchenge(routers.get(s-4),routers.get(w-4));}else {break;}}}}}}}}
实现效果:
主页面:
选项1:
选项2:
选项3:
结语:
你好,我是Blue. 为帮助别人少走弯路而写博客 !!!
如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。
如果你遇到了问题,自己没法解决,可以私信问我。
感谢订阅专栏 三连文章!!