RIP协议的模拟实现

内部网关协议 RIP(Routing Information Protocol)

内部网关协议RIP中,路由表更新的原则是找出到每个目的网络的最短距离,这种更新算法又称为距离向量算法,掌握该算法对于理解路由的机制有很大的帮助。
实验要求:
(1)试用已编写的程序求出路由器B更新后的路由表。(说明每一个更新的原因)
(2)试着演示当网络出现故障时,要经过比较长的时间才能将此信息传送到所有路由器的过程。(好消息传播的快,坏消息传播的慢)
(3)路由表的动态变化,按照时间定期更新路由表,直到稳定为止。

在这里插入图片描述这里是引用
在这里插入图片描述

代码:
路由器类:

import java.io.Serializable;
import java.util.List;
import java.util.Map;
//路由器
public class Router implements Serializable {
    private String routerName;//路由器地址
    private Map<String,Information> information;//路由器中路由表信息
    public Router() {
    }
    public Router(String routerName, Map<String, Information> information) {
        this.routerName = routerName;
        this.information = information;
    }
    public String getRouterName() {
        return routerName;
    }
    public Map<String, Information> getInformation() {
        return information;
    }
    public void setRouterName(String routerName) {
        this.routerName = routerName;
    }
    public void setInformation(Map<String, Information> information) {
        this.information = information;
    }
    @Override
    public String toString() {
        return "Router{\n"+
                "routerName:    "+routerName+
                "\ninformation:\n"+information.values()+
                "\n}"
                ;
    }
}

路由器中的路由表信息类:

import java.io.Serializable;
//路由表中的信息
public class Information implements Serializable {
    private String targetNetwork;  //目的网络
    private int distance;          //距离
    private String nextJumpRouter; //下一跳路由器
    public Information() {
    }
    @Override
    public String toString() {
        return "\n"+targetNetwork+
                "\t"+distance+
                "\t"+nextJumpRouter;
    }
    public void setTargetNetwork(String targetNetwork) {
        this.targetNetwork = targetNetwork;
    }
    public void setDistance(int distance) {
        this.distance = distance;
    }
    public void setNextJumpRouter(String nextJumpRouter) {
        this.nextJumpRouter = nextJumpRouter;
    }
    public String getTargetNetwork() {
        return targetNetwork;
    }
    public int getDistance() {
        return distance;
    }
    public String getNextJumpRouter() {
        return nextJumpRouter;
    }
    public Information(String targetNetwork, int distance, String nextJumpRouter) {
        this.targetNetwork = targetNetwork;
        this.distance = distance;
        this.nextJumpRouter = nextJumpRouter;
    }
}

路由表的动态变化:

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AutoUpdate extends Thread{
    private List<Router> routerList;//路由器集合
    public AutoUpdate() {
        this.routerList=new ArrayList<Router>();
        Map<String,Information> informationA=new HashMap<>();
        informationA.put("N1",new Information("N1",5,"A"));
        informationA.put("N2",new Information("N2",3,"C"));
        informationA.put("N6",new Information("N6",6,"F"));
        informationA.put("N8",new Information("N8",4,"E"));
        Router B=new Router("B",informationA);
        Map<String,Information> informationB=new HashMap<>();
        informationB.put("N1",new Information("N1",5,"A"));
        informationB.put("N2",new Information("N2",4,"F"));
        informationB.put("N3",new Information("N3",8,"C"));
        informationB.put("N6",new Information("N6",4,"D"));
        informationB.put("N8",new Information("N8",3,"E"));
        Router C=new Router("C",informationB);
        this.routerList.add(B);
        this.routerList.add(C);
    }
    @Override
    public void run() {
        System.out.println("开始自动更新路由表!!!!!!!!");
        while (true){
            try {
                Thread.sleep(1000);
                for(Router router:routerList){
                    for(Router router1:routerList){
                        Test.updateRouterTable(router,router1);
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            System.out.println("更新后:\n"+routerList);
        }
    }
    @Override
    public String toString() {
        return "AutoUpdate{" +
                "routerList=" + routerList +
                '}';
    }
    public List<Router> getRouterList() {
        return routerList;
    }
    public void setRouterList(List<Router> routerList) {
        this.routerList = routerList;
    }
}

测试类和方法:

import java.io.*;
import java.util.*;
public class Test {
    /**
     * 更新路由器的路由表
     * @param routerA   被更新的路由器
     * @param tmp       发来路由信息的路由器
     */
    public static void updateRouterTable(Router routerA,Router tmp) throws IOException, ClassNotFoundException {
        //如果没有信息,什么也不做
        if(tmp.getInformation()==null || tmp.getInformation().size()==0 || routerA==tmp){
            return;
        }
        //对tmp的复制,避免直接修改路由器C的路由表
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(baos);
        oos.writeObject(tmp);
        oos.close();
        byte[] bs=baos.toByteArray();
        ByteArrayInputStream bais=new ByteArrayInputStream(bs);
        ObjectInputStream ois=new ObjectInputStream(bais);
        Router routerB= (Router) ois.readObject();
        ois.close();
        //将发来路由信息的路由器的路由表中所有的距离都加1,并将B的下一跳全部改为路由器B的地址
        for(Information i:routerB.getInformation().values()){
            //距离小于16时才加
            if(i.getDistance()<16){
                i.setDistance(i.getDistance()+1);
            }
            i.setNextJumpRouter(routerB.getRouterName());
        }
        Information information=null;
        for(String s:routerB.getInformation().keySet()){
            //如果路由器A中原来不能到达这一网络,将这一网络加到路由器A中,并将下一跳改成B的地址
            if(!routerA.getInformation().containsKey(s)){
                //                         目的网络       距离                                 下一跳名称
                information=new Information(s,routerB.getInformation().get(s).getDistance(),routerB.getRouterName());
                routerA.getInformation().put(s,information);
            }else {
                //如果下一跳相同,替换原路由表中的项目,
                if(routerA.getInformation().get(s).getNextJumpRouter().equals(routerB.getRouterName())){
                    routerA.getInformation().put(s,routerB.getInformation().get(s));//直接替换
                }else {
                    //若收到的项目中的距离小于路由表中的距离,则进行更新,
                    if(routerB.getInformation().get(s).getDistance()<routerA.getInformation().get(s).getDistance()){
                        routerA.getInformation().put(s,routerB.getInformation().get(s));
                    }
                }
            }
        }
    }
    //更新路由器B的路由表
    public static void update() throws IOException, ClassNotFoundException {
        Map<String,Information> informationA=new HashMap<>();
        informationA.put("N1",new Information("N1",5,"A"));
        informationA.put("N2",new Information("N2",3,"C"));
        informationA.put("N6",new Information("N6",6,"F"));
        informationA.put("N8",new Information("N8",4,"E"));
        Router B=new Router("B",informationA);
        Map<String,Information> informationB=new HashMap<>();
        informationB.put("N1",new Information("N1",5,""));
        informationB.put("N2",new Information("N2",4,""));
        informationB.put("N3",new Information("N3",8,""));
        informationB.put("N6",new Information("N6",4,""));
        informationB.put("N8",new Information("N8",3,""));
        Router C=new Router("C",informationB);
        System.out.println("原B路由器:\n"+B);
        System.out.println("C路由器:\n"+C);
        updateRouterTable(B,C);
        System.out.println("更新后的B路由器"+B);
    }
    //坏消息传播的慢
    public static void func2() throws IOException, ClassNotFoundException {
        Map<String,Information> informationA=new HashMap<>();
        //informationA.put("N1",new Information("N1",1,""));  //正常情况
        Router A=new Router("A",informationA);
        Map<String,Information> informationB=new HashMap<>();
        informationB.put("N1",new Information("N1",2,"A"));
        Router B=new Router("B",informationB);
        System.out.println("原A路由器:\n"+A);
        System.out.println("----------------------------------------");
        System.out.println("原B路由器:\n"+B);
        System.out.println("----------------------------------------");
        while ( B.getInformation().get("N1").getDistance()!=16){
            updateRouterTable(A,B);
            System.out.println("A路由器变为"+A);
            updateRouterTable(B,A);
            System.out.println("B路由器变为"+B);
        }
        System.out.println("-----------------------------------------");
        System.out.println("更新后的A路由器"+A);
        System.out.println("-----------------------------------------");
        System.out.println("更新后的B路由器"+B);
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String choose="";               //输入的选项
        Scanner scanner=new Scanner(System.in);
        while(true){
            System.out.println("1.求出路由器B更新后的路由表");
            System.out.println("2.好消息传播的快,坏消息传播的慢");
            System.out.println("3.路由表的动态变化,按照时间定期更新路由表,直到稳定为止");
            System.out.println("4.结束");
            choose=scanner.nextLine();
            switch (choose){
                case "1":
                    update();
                    break;
                case "2":
                    func2();
                    break;
                case "3":
                    //创建一个路由器
                    Map<String,Information> informationA=new HashMap<>();
                    informationA.put("N9",new Information("N9",5,"H"));
                    informationA.put("N10",new Information("N10",3,"I"));
                    informationA.put("N11",new Information("N11",6,"J"));
                    informationA.put("N12",new Information("N12",4,"K"));
                    Router D=new Router("D",informationA);
                    //开始自动更新路由表
                    AutoUpdate autoUpdate=new AutoUpdate();
                    autoUpdate.start();
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //3秒后新增一个路由器并自动更新
                    System.out.println("增加了一个路由器!!!!!!!!!!!!!!!!!!!!");
                    autoUpdate.getRouterList().add(D);
                    break;
                case "4":
                    System.exit(0);
                    break;
            }
        }
    }
}

运行结果:
1.路由器B更新后的路由表:
在这里插入图片描述
2.坏消息传播的慢模拟过程:
在这里插入图片描述
3.路由表的动态变化:
在这里插入图片描述
如有错误希望指出,谢谢!

  • 19
    点赞
  • 128
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RIP(Routing Information Protocol)是一种路由协议,它可以让路由器自动学习并传递网络拓扑信息,帮助网络中的路由器进行动态路由选择。在Qt Creator中实现RIP协议模拟,可以通过以下步骤实现: 1. 创建Qt项目并添加必要的头文件和源文件。 2. 在头文件中定义RIP协议相关的数据结构和函数。 3. 在源文件中实现RIP协议相关的函数,包括路由表的初始化、更新和广播等操作。 4. 在主函数中创建多个线程,每个线程代表一个路由器,通过UDP协议模拟路由器之间的通信。 5. 在线程中实现路由器的初始化和循环更新路由表的过程。 6. 在主函数中启动所有线程,开始模拟RIP协议的运行。 需要注意的是,RIP协议是一种基于UDP的协议,需要使用Qt中的QUdpSocket类进行通信。同时,为了模拟实际网络中的路由器,可以使用Qt中的QThread类创建多个线程,每个线程代表一个路由器。 下面是一个简单的RIP协议模拟示例代码,供参考: ```c++ // 定义RIP协议相关的数据结构和函数 struct RIPEntry { uint32_t address; uint32_t mask; uint32_t nextHop; uint32_t metric; }; struct RIPPacket { uint8_t command; uint8_t version; uint16_t zero; RIPEntry entries[25]; }; void initRoutingTable(); void updateRoutingTable(QHostAddress sender, RIPPacket packet); void broadcastRoutingTable(); // 实现RIP协议相关的函数 void initRoutingTable() { // 初始化路由表,包括本路由器的直接连接网段和默认路由 } void updateRoutingTable(QHostAddress sender, RIPPacket packet) { // 解析收到的RIP数据包,更新路由表 } void broadcastRoutingTable() { // 广播本路由器的路由表信息给相邻路由器 } // 在线程中实现路由器的初始化和循环更新路由表的过程 void RouterThread::run() { initRoutingTable(); while (true) { // 循环更新路由表 msleep(5000); // 休眠5秒后再次更新路由表 } } // 在主函数中创建多个线程,模拟多个路由器之间的通信 int main(int argc, char *argv[]) { QApplication a(argc, argv); // 创建多个线程,每个线程代表一个路由器 RouterThread *router1 = new RouterThread(); RouterThread *router2 = new RouterThread(); RouterThread *router3 = new RouterThread(); // 启动所有线程 router1->start(); router2->start(); router3->start(); return a.exec(); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值