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:

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:

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,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. 为帮助别人少走弯路而写博客 !!!

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/956987.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

32V/4A,降压DCDC转换器CP8384百分百占空比输出ESOP8封装,可适用HUB等电路设计

特点&#xff1a; ● Supply Voltage Range: 4.1V~32V ● Input voltage up to 40V ● 4A Continuous Output Current ● Up to 95% Output Efficiency ● CC/CV control ● 350kHz Switching Frequency ● Built-in Soft Start ● 100% Maximum Duty Cycle ● No External Com…

缓存、数据库双写一致性解决方案

双写一致性问题的核心是确保数据库和缓存之间的数据同步&#xff0c;以避免缓存与数据库数据不同步的问题&#xff0c;尤其是在高并发和异步环境下。本文将探讨双写一致性面临的主要问题和解决方案&#xff0c;重点关注最终一致性。 本文讨论的是最终一致性问题 双写一致性面…

【学习笔记15】如何在非root服务器中,安装属于自己的redis

一、下载安装包 官网下载黑马程序员给的安装包&#xff08;redis-6.2.6&#xff09; 二、将安装包上传至服务器 我将安装包上传在我的文件夹/home/XXX&#xff0c;指定路径中/src/local/redis/&#xff0c;绝对路径为/home/XXX/src/local/redis/解压安装包 XXXomega:~$ cd …

计算机网络 (51)鉴别

前言 计算机网络鉴别是信息安全领域中的一项关键技术&#xff0c;主要用于验证用户或信息的真实性&#xff0c;以及确保信息的完整性和来源的可靠性。 一、目的与重要性 鉴别的目的是验明用户或信息的正身&#xff0c;对实体声称的身份进行唯一识别&#xff0c;以便验证其访问请…

【大模型】ChatGPT 高效处理图片技巧使用详解

目录 一、前言 二、ChatGPT 4 图片处理介绍 2.1 ChatGPT 4 图片处理概述 2.1.1 图像识别与分类 2.1.2 图像搜索 2.1.3 图像生成 2.1.4 多模态理解 2.1.5 细粒度图像识别 2.1.6 生成式图像任务处理 2.1.7 图像与文本互动 2.2 ChatGPT 4 图片处理应用场景 三、文生图操…

后端:MyBatis

文章目录 1. MyBatis1-1. Mybatis 工具类的封装1-2. Mybatis 通过集合或实体类传递参数-实现插入数据(增)1-3. MyBatis 实现删除数据(删)1-4. MyBatis 实现修改数据(改)1-5. MyBatis 实现查询数据(查) 2. MyBatis 配置文件中的一些标签和属性2-1.environments标签2-2. dataSour…

将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(1.标准版)

问题 项目里使用了 AzureBlob 存储了用户上传的各种资源文件&#xff0c;近期 AzureBlob 的流量费用增长很快&#xff0c;想通过分析Blob的日志&#xff0c;获取一些可用的信息&#xff0c;所以有了这个需求&#xff1a;将存储账户的日志&#xff08;读写&#xff0c;审计&…

数字化时代,传统代理模式的变革之路

在数字化飞速发展的今天&#xff0c;线上线下融合&#xff08;O2O&#xff09;成了商业领域的大趋势。这股潮流&#xff0c;正猛烈冲击着传统代理模式&#xff0c;给它带来了新的改变。 咱们先看看线上线下融合现在啥情况。线上渠道那是越来越多&#xff0c;企业纷纷在电商平台…

【AI | pytorch】torch.polar的使用

一、torch.polar的使用 torch.polar 是 PyTorch 中用来生成复数张量的一个函数&#xff0c;但它与数学中的复数表达式 ( z re^{i\theta} ) 是等价的。 具体来说&#xff0c;torch.polar(abs, angle) 接受两个实数张量参数&#xff1a; abs&#xff1a;表示复数的模长&#…

LeetCode 110.平衡二叉树

题目描述 给定一个二叉树&#xff0c;判断它是否是平衡二叉树。 示例 1&#xff1a; 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,3,3,null,null,4,4] 输出&#xff1a;false 示例 3&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;true 提示&#xff1a; …

数据结构(Java版)第四期:ArrayLIst和顺序表(上)

目录 一、顺序表 1.1. 接口的实现 二、ArrayList简介 2.1. ArrayList的构造 2.2. ArrayList的常见操作 2.3. ArrayList的扩容机制 三、ArrayList的具体使用 3.1. 洗牌算法 3.2. 杨辉三角 一、顺序表 上一期我们讲到过&#xff0c;顺序表本质上和数组是差不多的&#…

阿里云 Serverless 助力盟主直播:高并发下的稳定性和成本优化

在直播场景中&#xff0c;阿里云 Serverless 应用引擎 SAE 提供的无缝弹性伸缩与极速部署能力&#xff0c;确保直播间高并发时的流畅体验&#xff0c;降低了我们的运营成本&#xff0c;简化了运维流程。结合阿里云云原生数据库 PolarDB 的 Serverless 能力&#xff0c;实现了数…

【机器学习实战入门】基于深度学习的乳腺癌分类

什么是深度学习&#xff1f; 作为对机器学习的一种深入方法&#xff0c;深度学习受到了人类大脑和其生物神经网络的启发。它包括深层神经网络、递归神经网络、卷积神经网络和深度信念网络等架构&#xff0c;这些架构由多层组成&#xff0c;数据必须通过这些层才能最终产生输出。…

Qt之QDjango-db的简单使用

QDjango是一款由C编写、依托于Qt库的Web开发框架&#xff0c;其设计理念受到了广受欢迎的Python框架Django的影响。这个项目旨在提供一个高效、灵活且易于使用的工具集&#xff0c;帮助开发者构建高质量的Web应用。其项目地址: https://gitcode.com/gh_mirrors/qd/qdjango&…

[2025分类时序异常检测指标R-AUC与VUS]

梳理了一下分类中常见的指标&#xff0c;这些指标与时序异常检测中新提出的A-RUC与VUS之间的关系 真正例(True Positive,TP): 被正确识别为正样本的数量。真负例(True Negative,TN): 被正确识别为负样本的数量。假正例(False Positive ,FP): 被错误识为正样本数量假负例(Fals…

python3GUI--仿崩坏三二次元登录页面(附下载地址) By:PyQt5

文章目录 一&#xff0e;前言二&#xff0e;预览三&#xff0e;实现方案1.实现原理1.PyQt52. 具体实现 2.UI设计1.UI组件化、模块化2.UI设计风格思路 3.项目代码结构4.使用方法3.代码分享1.支持跳转网页的QLabel组件2.三角形ICON按钮 四&#xff0e;总结 大小&#xff1a;33.3 …

STM32 FreeRTOS中断管理

目录 FreeRTOS的中断管理 1、STM32中断优先级管理 2、FreeRTOS任务优先级管理 3、寄存器和内存映射寄存器 4、BASEPRI寄存器 5、FreeRTOS与STM32中断管理结合使用 vPortRaiseBASEPRI vPortSetBASEPRI 6、FromISR后缀 7、在中断服务函数中调用FreeRTOS的API函数需注意 F…

如何在idea中搭建SpringBoot项目

如何在idea中快速搭建SpringBoot项目 目录 如何在idea中快速搭建SpringBoot项目前言一、环境准备&#xff1a;搭建前的精心布局 1.下载jdk &#xff08;1&#xff09;安装JDK&#xff1a;&#xff08;2&#xff09;运行安装程序&#xff1a;&#xff08;3&#xff09;设置安装…

Linux:expect spawn简介与用法

一、背景 大家在使用linux系统的很多时候&#xff0c;都用linux指令来实现一些操作&#xff0c;执行特定的job&#xff0c;有时一些场景中需要执行交互指令来完成任务&#xff0c;比如ssh登录这个命令大家一定很熟悉&#xff1a; ssh-keygen -t rsa # 以及 ssh-copy-id -i /hom…

服务器硬盘RAID速度分析

​ 在现代数据中心和企业环境中&#xff0c;服务器的存储性能至关重要&#xff0c;RAID&#xff08;独立磁盘冗余阵列&#xff09;技术通过将多块硬盘组合成一个逻辑单元&#xff0c;提供了数据冗余和性能优化&#xff0c;本文将详细探讨不同RAID级别对服务器硬盘速度的影响&am…