2019-05-01 10:48:20 DZMNLFH 阅读数 820
  • CCNP路由实验专题讲解视频课程--策略路由(PBR)篇

    更多课程,请百度搜索“晁海江”。 PBR是根据一定的策略进行报文转发,因此策略路由是一种比目的路由更灵活的路由机制。在路由器转发一个数据报文时,首先根据配置的规则对报文进行过滤,匹配成功则按照一定的转发策略进行报文转发。这种规则可以是基于标准和扩展访问控制列表,也可以基于报文的长度;而转发策略则是控制报文按照指定的策略路由表进行转发,也可以修改报文的IP优先字段。因此,策略路由是对传统IP路由机制的有效增强。

    5132 人正在学习 去看看 晁海江

RIP的算法思想:
(1)收到相邻路由器(其地址为X)的一个RIP报文,先修改此RIP报文中的所有项目:将“下一跳”字段中的地址都改为X,并将所有的“距离”字段的值加1。
(2)对修改后的RIP报文中的每一个项目,重复以下步骤:
若项目中的目的网络不在路由表中,则将该项目添加到路由表中。
否则
若下一跳字段给出的路由器地址是同样的,则将收到的项目替换原路由表中的项目。
否则
若收到的项目中的距离小于路由表中的距离,则进行更新,
否则,什么也不做
(3)若3分钟还没有收到相邻路由器的更新路由表,则将此相邻路由器记为不可达的路由器,即将距离置为16(距离为16表示不可达)
(4)返回。
**
实验部分截图如下:

在这里插入图片描述
在这里插入图片描述

废话少说直接上源代码(本代码发送数据为了方便用的是UDP,读者可以将其改为更为安全的TCP)*

RipLine类封装了路由表的三个基本信息即(目的网络地址,距离,下一跳)


public class RipLine {
    //表结构
    private String ripnet;//目的网络地址
    private String ripnext;//距离
    private int ripdistance;//下一跳

    public String getRipnet() {
        return ripnet;
    }

    public String getRipnext() {
        return ripnext;
    }

    public int getRipdistance() {
        return ripdistance;
    }

    public void setRipnet(String ripnet) {
        this.ripnet = ripnet;
    }

    public void setRipnext(String ripnext) {
        this.ripnext = ripnext;
    }

    public void setRipdistance(int ripdistance) {
        this.ripdistance = ripdistance;
    }

}

类RipTable在类RipLine的基础上加上了表名称进一步封装了路由表,并且将表结构用List储存起来,方便后续操作


import java.util.ArrayList;
import java.util.List;

public class RipTable {
    private String tableName;//表名称
    private List<RipLine> ripTableList = new ArrayList<RipLine>();//将表用List储存起来

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public List<RipLine> getRipTableList() {
        return ripTableList;
    }


    public void addRipTableList(RipLine ripTableLists) {
        ripTableList.add(ripTableLists);
    }

}


类Controller是核心类,它里面封装了Rip协议用到的各种算法,方法里面都有相应的注释

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Scanner;

///控制层
public class Controller {
    //比较连个表的目的路由地址
    public static int IndexTables(RipLine ripLine1, RipTable s_table) {
        int flag = -1;
        for (int i = 0; i < s_table.getRipTableList().size(); i++) {
            if (ripLine1.getRipnet().equals(s_table.getRipTableList().get(i).getRipnet())) {
                flag = i;
                break;
            }

        }
        return flag;
    }
    //复制一个副本
    public static RipTable CopyRip(RipTable stable){
        RipTable copytable=new RipTable();
        copytable.setTableName(stable.getTableName());
        RipLine ripLines=null;
        for (int i=0;i<stable.getRipTableList().size();i++)
        {
            ripLines=new RipLine();
            ripLines.setRipnet(stable.getRipTableList().get(i).getRipnet());
            ripLines.setRipdistance(stable.getRipTableList().get(i).getRipdistance());
            ripLines.setRipnext(stable.getRipTableList().get(i).getRipnext());
            copytable.addRipTableList(ripLines);
        }
        return copytable;
    }
    public static RipTable CompareRip(RipTable s_table, RipTable c_table) {

        int index = 0;

        for (int i = 0; i < c_table.getRipTableList().size(); i++) {
            //目的网络不相等需要加进去
            index = IndexTables(c_table.getRipTableList().get(i), s_table);
            if (index == -1) {
                System.out.println("第" + i + "目的网络不相同");
                s_table.addRipTableList(c_table.getRipTableList().get(i));

            } else {//目的网络相等情况下,比较下一跳是否相等

                if (c_table.getRipTableList().get(i).getRipnext().equals(s_table.getRipTableList().get(index).getRipnext())) {
                    System.out.println("下一跳相同");
                    s_table.getRipTableList().get(index).setRipnet(c_table.getRipTableList().get(i).getRipnet());
                    s_table.getRipTableList().get(index).setRipdistance(c_table.getRipTableList().get(i).getRipdistance());
                    s_table.getRipTableList().get(index).setRipnext(c_table.getRipTableList().get(i).getRipnext());
                } else {

                    if (c_table.getRipTableList().get(i).getRipdistance() < s_table.getRipTableList().get(index).getRipdistance()) {
                        //替换小的
                        System.out.println("替换小的");
                        s_table.getRipTableList().get(index).setRipnet(c_table.getRipTableList().get(i).getRipnet());
                        s_table.getRipTableList().get(index).setRipdistance(c_table.getRipTableList().get(i).getRipdistance());
                        s_table.getRipTableList().get(index).setRipnext(c_table.getRipTableList().get(i).getRipnext());
                    }

                }

            }
        }

        return s_table;
    }

    //修改路由距离加一
    public static RipTable ModifyRip(RipTable table1) {

        RipTable m_table = new RipTable();
        RipLine m_ripLine = new RipLine();
        m_table.setTableName(table1.getTableName());
        for (int i = 0; i < table1.getRipTableList().size(); i++) {

            m_ripLine.setRipnet(table1.getRipTableList().get(i).getRipnet());
            m_ripLine.setRipdistance(table1.getRipTableList().get(i).getRipdistance() + 1);
            //  m_ripLine.setRipnext(table1.getRipTableList().get(i).getRipnext());
            m_ripLine.setRipnext(table1.getTableName());
            m_table.addRipTableList(m_ripLine);

            m_ripLine = new RipLine();

        }

        return m_table;
    }

    //分割成字符串
    public static String EncodeData(RipTable table) {

        List<RipLine> ripLines = table.getRipTableList();
        String strs = "";
        strs += table.getTableName();
        strs += "#";
        for (int i = 0; i < ripLines.size(); i++) {

            strs += ripLines.get(i).getRipnet();
            strs += "@";
            strs += ripLines.get(i).getRipdistance();
            strs += "@";
            strs += ripLines.get(i).getRipnext();
            strs += "$";

        }

        return strs;
    }

    //将字符合并成RipTable表
    public static RipTable mergeData(String str) {
        RipTable ripTable = new RipTable();
        RipLine ripLine = new RipLine();
        int times = 0;
        String temp = "";
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == '#' && times == 0) {
                ripTable.setTableName(temp);
                temp = "";
                times++;
            } else if (str.charAt(i) == '@' && times == 1) {
                ripLine.setRipnet(temp);
                temp = "";
                times++;
            } else if (str.charAt(i) == '@' && times == 2) {
                ripLine.setRipdistance(Integer.parseInt(temp));
                times++;
                temp = "";
            } else if (str.charAt(i) == '$' && times == 3) {
                ripLine.setRipnext(temp);
                temp = "";
                times++;
                ripTable.addRipTableList(ripLine);
                ripLine = new RipLine();
            } else {
                temp += str.charAt(i);
                if (times == 4) times = 1;
            }
        }
        return ripTable;
    }

    //初始化路由表
    public static RipTable initTable() throws IOException {

        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        RipTable table = new RipTable();
        System.out.println("输入表名称");
        Scanner p = new Scanner(System.in);
        table.setTableName(input.readLine());
        RipLine ripLine = null;
        System.out.println("数目");
        int n = p.nextInt();
        for (int i = 0; i < n; i++) {
            ripLine = new RipLine();
            System.out.println("请输入第" + (i + 1) + "条目的地址");
            String temp = input.readLine();
            ripLine.setRipnet(temp);
            System.out.println("请输入第" + (i + 1) + "条距离");
            ripLine.setRipdistance(p.nextInt());
            System.out.println("请输入第" + (i + 1) + "条下一跳");
            ripLine.setRipnext(input.readLine());
            table.addRipTableList(ripLine);

        }

        return table;
    }

    //打印路由表
    public static void showTable(RipTable table) {
        System.out.println("表名称:");
        System.out.println(table.getTableName());
        System.out.println("目的网络-" + "--向量距离---" + "下一跳-----");
        for (int j = 0; j < table.getRipTableList().size(); j++) {
            System.out.println("    " + table.getRipTableList().get(j).getRipnet() + "         " + table.getRipTableList().get(j).getRipdistance() + "           " + table.getRipTableList().get(j).getRipnext());
        }
    }
}

类RipServer负责接收RipClient发过来的路由表,并进行更新操作,也可以发送路由表给RipClient


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class RipServer extends Thread {

    private static DatagramSocket socket;
    private static DatagramPacket packet;
    private static InetAddress address;

    public static void receive(DatagramSocket socket) throws Exception {

        byte[] data = new byte[1024];

        packet = new DatagramPacket(data, data.length);

        socket.receive(packet);

        String info = new String(data, 0, data.length);

        RipTable table = Controller.initTable();
        Controller.showTable(table);

        String temps = Controller.EncodeData(table);
        RipTable table1 = Controller.mergeData(info);
        System.out.println("收到的原路由表信息");
        Controller.showTable(table1);

        RipTable m_table = Controller.ModifyRip(table1);
        System.out.println("距离加一后的路由表信息");
        Controller.showTable(m_table);
        RipTable stable=Controller.CopyRip(table);
        RipTable table2 = Controller.CompareRip(stable, m_table);
        System.out.println("最后跟新后的路由");
        Controller.showTable(table2);
        send(temps, socket, packet);

    }


    public static void send(String temps, DatagramSocket socket, DatagramPacket packet) throws Exception {

        address = packet.getAddress();

        int port = packet.getPort();

        // RipTable table = Controller.initTable();

        // String temps = Controller.EncodeData(table);

        byte[] data2 = temps.getBytes();

        DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
        socket.send(packet2);

        socket.close();

    }

    public void run() {
        try {
            receive(socket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {

        socket = new DatagramSocket(10010);
        new RipServer().start();

    }

}

类RipClient发送路由表给RipServer,同时也可以接收RipServer发过来的路由表,进行更新操作


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class RipClient implements Runnable{
    private static DatagramPacket packet;
    private static DatagramSocket socket;
    private static InetAddress address;
    private static RipTable ripTableClient;//全局用于比较路由信息
    public void run(){
        try {
            recived(socket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void send(DatagramSocket socket,DatagramPacket packet)throws Exception{
        address = InetAddress.getByName("127.0.0.1");
        int port = 10010;
        RipTable tabletemp=Controller.initTable();
        ripTableClient = Controller.CopyRip(tabletemp);
        String strs=Controller.EncodeData(tabletemp);
        byte[] data = strs.getBytes();
        packet =new DatagramPacket(data,data.length,address,port);
        socket.send(packet);

    }
    public static void recived(DatagramSocket socket)throws Exception{

        byte[] data2=new byte[1024];

        DatagramPacket packet2 = new DatagramPacket(data2, data2.length);

        socket.receive(packet2);

        String raply = new String(data2, 0, packet2.getLength());

        RipTable table1=Controller.mergeData(raply);
        System.out.println("本机的路由表");
        Controller.showTable(ripTableClient);
        System.out.println("收到的路由表");
        Controller.showTable(table1);

        RipTable tabletemp1=Controller.ModifyRip(table1);
        System.out.println("距离加一");
        Controller.showTable(tabletemp1);
        RipTable tabletemp2 = Controller.CompareRip(ripTableClient, table1);
        System.out.println("最后跟新的路由表");
        Controller.showTable(tabletemp2);
        socket.close();

    }
    public static void main(String[] args) throws Exception{

        socket = new DatagramSocket();
        send(socket,packet);
        new Thread(new RipClient()).start();

    }

}

如有疑问欢迎咨询loufanghong136@163.com

2013-07-02 10:36:38 andamajing 阅读数 2623
  • CCNP路由实验专题讲解视频课程--策略路由(PBR)篇

    更多课程,请百度搜索“晁海江”。 PBR是根据一定的策略进行报文转发,因此策略路由是一种比目的路由更灵活的路由机制。在路由器转发一个数据报文时,首先根据配置的规则对报文进行过滤,匹配成功则按照一定的转发策略进行报文转发。这种规则可以是基于标准和扩展访问控制列表,也可以基于报文的长度;而转发策略则是控制报文按照指定的策略路由表进行转发,也可以修改报文的IP优先字段。因此,策略路由是对传统IP路由机制的有效增强。

    5132 人正在学习 去看看 晁海江

路由信息协议RIP:是内部网关协议中得到最先广泛使用的协议,是一种分布式的基于距离向量的路由选择协议。

路由信息协议RIP要求网络中的每一个路由器都要维护一个从它自己到目的网络的距离记录,这里的距离指的是路由器到目的网络所需经过的路由器的个数。

RIP中的距离也称为跳数,每经过一个路由器,跳数都会加1,RIP协议要求一条路径上所能包含的最大路由数是15个,如果超过,即相当于不可达,所以RIP协议只适合于小型网络。

RIP协议不能在两个网络之间使用多条路由,它会选择一条具有最少路由数的路由,哪怕还有一条更快的但是却含有更多路由器的路由。

我们知道每一个路由器都要不断的跟其他路由器交换信息,但是,和哪些路由器交换信息?交换什么信息?什么时间交换信息?

RIP协议特点:

(1)               仅和相邻的路由器交换路由信息,相邻指的是之间的通信不需要经过其他路由器;

(2)               交换的信息是当前本路由器所知道的的所有路由信息;

(3)               按照固定的时间间隔交换路由信息;

路由表中最主要的信息是:到达某个网络的距离和下一跳的路由器。更新的原则是找出到达目的网络的最短距离。

RIP协议使用的是距离向量算法。

距离向量算法的基础是Bellman-Ford算法。距离向量算法的步骤如下所示:

(1)               对地址为X的相邻路由器发送来的RIP报文,首先修改报文中个所有项目:把下一跳地址修改为X,将距离字段(跳数)加1,每个项目包含三个有效字段:目的网络N,距离(跳数)d,下一跳路由X。

(2)               对修改后的RIP报文中的每个项目进行比较,步骤如下:

l  若原来的路由表中没有目的网络N,则将其添加到本路由器的路由表中。

l  否则(若原来的路由表中有目的网络N,这是需要查看下一跳地址),若下一跳路由器地址是X,则用收到的项目替换路由表中的项目。若下一跳路由地址不是X,则比较收到项目的距离(跳数)项d和本路由器上的距离(跳数),如果小于,则对本路由器上的跳数进行更新,否则什么都不做。

(3)               如果3分钟后还没有收到相邻路由器的更新路由表,则将相邻路由器记为不可达的路由器,并将距离设置为16。

RIP协议让一个自制系统内的相邻路由器之间定期交换路由信息,使得每个路由器到目的网络的距离都是最短的。

RIP协议传输层使用的是UDP这种面向无连接的传输层协议。

RIP报文由首部和路由部分组成。

首部由4个字节组成,其中第一个字节是命令字段,表示当前报文的意义,1表示请求路由信息,2表示对请求路由信息的回应或者是未请求而自动发出的路由更新报文。第二个字节表示版本号,最后的两个字节为全0域,是为了4字节对齐。

路由部分由若干个路由信息组成(最多包含25个),每个路由信息由20个字节组成。格式如下:



需要说明是,地址族标识符用来标识所使用的地址协议,路由标记填入的是自制系统号ASN。而距离字段填写的是1-16,1表示直接交付,16表示不可达。

RIP2可支持边长子网掩码和CIDR,同时还提供简单的鉴别过程支持多播。

RIP2当使用鉴别功能时,将会占用一个路由信息,在这个路由信息的地址族标识符中存放0XFFFF,在路由标记字段中放入鉴别类型。此时最多只能传送24个路由信息。

RIP的优缺点:

(1)   优点:实现简单,开销较小。

(2)   限制的网络的规模;路由器之间交换的路由信息是路由器的完整路由表,随着网络增大,开销也会增大。

(3)   “坏消息”传播的慢,使得更新的收敛过程过长。

2019-12-31 15:37:09 qq_43576028 阅读数 224
  • CCNP路由实验专题讲解视频课程--策略路由(PBR)篇

    更多课程,请百度搜索“晁海江”。 PBR是根据一定的策略进行报文转发,因此策略路由是一种比目的路由更灵活的路由机制。在路由器转发一个数据报文时,首先根据配置的规则对报文进行过滤,匹配成功则按照一定的转发策略进行报文转发。这种规则可以是基于标准和扩展访问控制列表,也可以基于报文的长度;而转发策略则是控制报文按照指定的策略路由表进行转发,也可以修改报文的IP优先字段。因此,策略路由是对传统IP路由机制的有效增强。

    5132 人正在学习 去看看 晁海江

题目

假定网络中的路由器B的路由表有如下的项目(这三列分别表示“目的网络”、“距离”和“下一跳”路由器):
N1 7 A
N2 2 C
N6 8 F
N8 4 E
N9 4 F
现在B收到从C发来的路由信息(这两列分别表示“目的网络”和“距离”):
N2 4
N3 8
N6 4
N8 3
N9 5
试求出路由器B更新后的路由表(详细说明每一个步骤)。
在这里插入图片描述

解析

在这里插入图片描述

备注

如有问题请留言

2018-11-29 11:50:32 tbib123456 阅读数 151
  • CCNP路由实验专题讲解视频课程--策略路由(PBR)篇

    更多课程,请百度搜索“晁海江”。 PBR是根据一定的策略进行报文转发,因此策略路由是一种比目的路由更灵活的路由机制。在路由器转发一个数据报文时,首先根据配置的规则对报文进行过滤,匹配成功则按照一定的转发策略进行报文转发。这种规则可以是基于标准和扩展访问控制列表,也可以基于报文的长度;而转发策略则是控制报文按照指定的策略路由表进行转发,也可以修改报文的IP优先字段。因此,策略路由是对传统IP路由机制的有效增强。

    5132 人正在学习 去看看 晁海江

RIP 基本原理

        RIP是基于贝尔曼-福特算法的一种内部网关路径矢量协议。RIP基于UDP封装路由信息,在520号端口上侦听并接收来自远程路由器发送的路由更新信息,并对本地路由器中的路由表做相应的修改在广播给其他路由器。路由器每隔30s向外广播路由信息,如果经过180s都没有收到对端路由器的路由更新信息,则将来自此路由器的路由信息标志为不可达,再经过120s都还没有收到路由更新信息,则将路由从该路由表中删除。RIP使用跳数来衡量到达网络的距离,与路由器直接相连的网络距离为0,每增加一台路由器,跳数加1,当跳数为16跳时,定义为不可达,所以RIP协议规定最大跳数为15跳。

运行RIP协议的路由器路由表更新过程

       收到远程路由器的路由更新信息之后,将收到的路由表与自身路由表进行比较,如果本地路由表里的路由条目中没有并且远程路由器的路由表里有路由条目,则本地路由器新增该条路由条目,并且跳数加1,如果本地路由表中已有路由条目,并且下一跳是该邻居路由器时,无论度量值增大还是减少,都更新该路由项,该路由条目的下一跳不是该邻居路由器时,只在度量值减少时更新路由条目。

RIP报文格式

       RIP有两个版本,RIPv1和RIPv2。RIPv1不支持可变长子网掩码(VLSM),RIPv2支持可变长子网掩码以及支持路由聚合和无类域间路由,并且支持明文验证和MD5密文验证。RIPv1使用广播方式发送报文,RIPv2使用广播和多播方式发送报文,多播地址为224.0.0.9。使用多播的好处就是可以避免没有运行RIP的网段接收RIP报文,还可以避免运行RIPv1的网段错误接收和处理RIPv2中带有子网掩码的路由。

       RIPv1报文包括一个命令标识符(Command)、一个版本号(Version)、若干条路由条目构成,路由条目包括IP地址和度量值。RIPv2报文头部与RIPv1的一样,但是路由条目里面还包含了子网掩码以及下一跳地址。RIP报文头部4个字节,每条路由条目20个字节,一个RIP数据报文的大小为4+20*25+8=512字节,8字节为UDP的头部长度。

RIP防环机制

      RIP产生环路的原因:一台路由器从邻居路由器学习到一条路由,假设由于链路原因该路由条目在邻居路由器上已失效,但是该路由器又将这条路由信息发送给邻居路由器,这样是邻居路由器误认为可以通过这台路由器到达目的网络,这样两台相邻的路由器周期性地交换路由信息,使得该条路由信息不断在两台路由器之间传送,直至跳数增至16跳时才结束,这样就产生了环路。

解决环路方法1:水平分割。

      路由器不允许把从一个接口进来的更新又通过该接口转发出去。简单来说就是从邻居路由器学习来的路由信息不再发送给该邻居路由器。

解决环路方法2:毒性反转

      当网络发生故障时,路由器将路由表中的到达该网络的路径开销设置为16,即不可达,邻居路由器收到网络不可达的通过后,向该路由器发送一个毒性反转的更新,用来确认网段上的所有路由器都收到网络不可达的通告信息。

解决环路方法3:触发更新

       路由器检测到网络拓扑发生变化的时候,立即发送触发更新信息给相邻路由器,需要与毒性反转一起结合使用。


2019-03-06 09:23:04 June_tree 阅读数 95
  • CCNP路由实验专题讲解视频课程--策略路由(PBR)篇

    更多课程,请百度搜索“晁海江”。 PBR是根据一定的策略进行报文转发,因此策略路由是一种比目的路由更灵活的路由机制。在路由器转发一个数据报文时,首先根据配置的规则对报文进行过滤,匹配成功则按照一定的转发策略进行报文转发。这种规则可以是基于标准和扩展访问控制列表,也可以基于报文的长度;而转发策略则是控制报文按照指定的策略路由表进行转发,也可以修改报文的IP优先字段。因此,策略路由是对传统IP路由机制的有效增强。

    5132 人正在学习 去看看 晁海江

工作原理

RIP是一种基于距离向量的路由选择协议。距离向量表示从一个网络到另一个网络所经过的路由器数量,也称跳数。最大值为15,可见RIP只适用于小型互联网。

RIP协议的特点:

  1. 仅和相邻路由器交换信息。
  2. 交换路由器自己的路由表。
  3. 定时交换信息。

距离向量算法

路由器对每一个相邻路由器发来的RIP报文进行如下操作:

  1. 对地址X发来的报文中的每一项进行修改,将下一跳地址改为X,距离+1。
  2. 对报文中的每一条,假设目的地址为N,若N不在本路由器的路由表中,则添加到本路由表。
  3. 否则,若本路由表中目的地址为N的项下一跳是X,则更新此条。(保留最新信息)
  4. 否则,保留距离较小的那一条。
  5. 若三分钟还没有收到相邻路由器发来的RIP报文,则将此路由器距离设为16,即不可到达。

RIP算法的优缺点

优点:实现简单,开销较小。
缺点:当网络出现故障时,要较长时间才能将此信息传送到所有路由器。(即好消息传得快,坏消息传的慢)

RIP路由协议的理解

阅读数 19833

没有更多推荐了,返回首页