计算机网络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();

    }

}

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

  • 7
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
用C写的rip协议 这是其中的广播request程序片段: void RouteInit() { int i,optval=0,length,error; routeNum = 0; // init local socket address and ip address GetLocalIP(); // init route table items for(i = 0; i < MAX_NUM; i++) { SetRouteEntry(&routeTable[i].routeInfo,"0.0.0.0",0,0); routeTable[i].isvalid = 0; routeTable[i].timer = 0; routeTable[i].statue = 0; inet_aton("0,0,0,0",&routeTable[i].sourceIPAddr); } // init request packet SetRoutePacket(&reqPacket,REQUEST); SetRouteEntry(&reqPacket.routeEntry[0],"0.0.0.0",0,16); // init response packet SetRoutePacket(&resPacket,RESPONSE); recvSockAddr.sin_family = AF_INET; recvSockAddr.sin_port = htons(PORT); recvSockAddr.sin_addr.s_addr = htonl(INADDR_ANY); sendSockAddr.sin_family = AF_INET; sendSockAddr.sin_port = htons(PORT); // inet_aton("240.255.255.255",&sendSockAddr.sin_addr); sendSockAddr.sin_addr.s_addr = htonl(INADDR_ANY); EntryInit(); sock = socket(AF_INET,SOCK_DGRAM,0); if(sock<0) { printf("cannot create a socket!\n"); exit(1); } if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&optval,sizeof(int)) != 0) { printf("cannot broadcast!\n"); close(sock); exit(1); } if(bind(sock,(struct sockaddr*)&recvSockAddr,sizeof(recvSockAddr))<0) { printf("cannot bind to port\n"); close(sock); exit(1); } length=sizeof recvSockAddr; getsockname(sock,(struct sockaddr*)&recvSockAddr,&length); printf("Port %d is opened. Listen for packet...\n",ntohs(recvSockAddr.sin_port)); FD_ZERO(&fdSet); FD_SET(sock,&fdSet); error = sendto(sock,&reqPacket,4+sizeof(struct ROUTE_ENTRY),0,(struct sockaddr*)(&sendSockAddr),sizeof(struct sockaddr)); if(error<0) { PrintEntry(&reqPacket.routeEntry[0]); printf("broadcast request packet failed! %d,%d,%d\n",error,sock,fdSet); } }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值