Java模拟路由协议-rip(路由器仿真实验)

前言:

好久不见,有段时间没有写文章了,本篇文章,由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:

java 复制代码
package com.example.Kclass;

/**
 * 路由表:
 * 1、目的网络
 * 2、距离
 * 3、下一跳路由器
 */
public class RouterTable implements Cloneable{
    private Integer AimNet;
    private Integer distance;
    private String NextRouter;


    public RouterTable() {
    }

    @Override
    protected 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:

java 复制代码
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:
java 复制代码
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

java 复制代码
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代码

java 复制代码
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,4

        for (int i=1;i<=4;i++){
            NetWork e =new NetWork();
            e.setId(i);
            netWorks.add(e);
        }
        //生成四个路由器
        //令四个路由器为5,6,7,8

        for (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,下一跳变为e1
        for (RouterTable table :Copye2){
            table.setDistance(table.getDistance()+1);
            table.setNextRouter(next);
        }
        e1.update(Copye2);

        //e2去更新e1
        String next2=e1.getId()+"";
        //深拷贝
        List<RouterTable> copy1 = e1.deepCopyRouterTables();
        //根据rip协议,让其距离加1,下一跳变为e2
        for (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. 为帮助别人少走弯路而写博客 !!!

如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 。想看更多 那就点个关注吧 我会尽力带来有趣的内容 😎。

如果你遇到了问题,自己没法解决,可以私信问我。

感谢订阅专栏 三连文章!!

相关推荐
工业互联网专业34 分钟前
基于springboot+vue的城市公交查询系统
java·vue.js·spring boot·毕业设计·源码·课程设计
G3G442 分钟前
Maven项目中没有.iml文件
java·maven·intellij-idea
落霞与孤鹭齐飞。。1 小时前
SSM宠物医院信息管理系统
java·开发语言·mysql·毕业设计·课程设计
程序人生771 小时前
打游戏时总是“红网”怎么回事,如何解决
网络·智能路由器
上海拔俗网络2 小时前
“AI 大模型内容安全审核软件系统:守护网络世界的卫士
java·团队开发
山兔12 小时前
21.1、网络设备安全概述
网络·安全·智能路由器
m0_748251083 小时前
PHP For 循环
android·java·php
m0_748254473 小时前
记录一下在Win上搭建RustDesk
java
我要学编程(ಥ_ಥ)3 小时前
初始JavaEE篇 —— 快速上手 SpringBoot
java·spring boot·spring·java-ee
摸鱼也很难3 小时前
安全开发 JavaEE && 反射机制 && 对象 成员变量 构造方法 成员方法 && 攻击链
java·java-ee·java安全