計算機網絡RIP協議的源代碼

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();

    }

}

如有疑問歡迎諮詢[email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章