中南大学计算机网络实验报告

中南大学

计算机网络实验报告

姓名:                              

学号:                             

班级:                              


实验一 分槽ALOHA协议仿真实验

【实验目的】

1.          掌握VB、VC++、VS或JAVA等集成开发环境编写仿真程序的方法;

2.          理解并掌握分槽ALOHA协议原理。

【实验内容】

编写仿真程序,对一定网络环境下MAC层的多路访问协议的分槽ALOHA协议进行实现。通过仿真,学习协议采取的介质访问管理,包括介质分配和冲突解决机制,并对协议的性能与理论结果进行比较分析。

【实验具体设计】

1.实验流程图

2. 关键代码说明:

此仿真实验中一共包括三个类。分别是Send.java、Pot.java、AlohaTest.java。在这三个类中,Pot中随机产生站点发送数据包的时间。Send根据站点发送的时间,判断是否发生冲突。如果发生冲突,则重发。

部分关键代码:

重发的时间的选择:

for(int i=1;i<6;i++){//当发生冲突的时候,重传,选择重发的时间

           while (al.get(0)==al.get(i)){

              al.set(i, rnd.nextInt(10));

              //compare();

           }

       }

站点的计数:

public void cycle(){

       int sum = a+b+c+d+e;

        for(;sum<=100;){

           sum = a+b+c+d+e;

           change();

       }

    }

3.  实验截图

【实验设备与实验环境】

1.       实验设备:联想E430

2.       实验环境:win7家庭版,使用eclipse编写。

【实验总结】

       通过这次实验,更加了解了分槽ALOHA协议的内容。学习了协议采用的介质访问管理。对于协议的性能有了更加深刻的理解。在实验中,曾遇到不少困难。但是通过老师与同学们的帮助都一一解决。这个ALOHA实验的比较简单。但是真实情况下的要复杂许多。并没有完全模拟出来。而且程序有些冗余。还需提高代码的编写能力。

【源代码】(java编写)

package alohalx_check;

public class AlohaTest {

    public static void main(String[] args){

        /*1.对于站点的初始化。一共有 五个站点。

         * 需要写一个关于站点的类。这个类里面包括随机发送数据包。

         *2.需要对每个站点随机发送数据包的时间进行判断。如果一样,则两个都需要重发。如果不一样,则继续发送下一个数据包。

         *  直到五个站点发送数据包的总数为100000。即需要对总的数据包数目计数。并且在控制台输出每一个站点数据包的发送情况。

         * */

        Send s1 = new Send();

        //s1.change();

        s1.cycle();

        //s1.init();

    }

}

package alohalx_check;

import java.util.Random;

public class Pot {

    /*1.可以随机发送数据包。

     * 2.随机发送的时间

     * */

    private int time;

    Random rnd = new Random();

    public void setTime(){

        time = rnd.nextInt(10); 

    }

    public int getTime(){

        return this.time;

    }

}

package alohalx_check;

import java.util.ArrayList;

import java.util.Random;

public class Send {//设置槽长为1,使用信道的时间为10.五个站点进行发送

    ArrayList al = new ArrayList();

         int a = 0;

         int b = 0;

         int c = 0;

         int d = 0;

         int e = 0;

       Random rnd = new Random();

    public void compare(){//在change中调用

        for(int n=1;n<=5;n++){

            for(int m=1;m<=5;m++){

                if(n!=m){

                    if(al.get(n)==al.get(m)){

                        al.set(n, 10);

                        al.set(m, 10);

                    }

                }

            }

        }

    }

    public void change(){

        al.add(10);

        al.add(1,rnd.nextInt(10));

        al.add(2,rnd.nextInt(10));

        al.add(3,rnd.nextInt(10));

        al.add(4,rnd.nextInt(10));

        al.add(5,rnd.nextInt(10));

            compare();

            if(al.get(1)!=al.get(0)){          

                System.out.println("站点1"+"成功第"+(++a)+"个数据包");

            }

            else {

                System.out.println("站点1"+"发送第"+(++a)+"个数据包发生阻塞");

                --a;

            }

            if(al.get(2)!=al.get(0)){

                System.out.println("站点2"+"成功第"+(++b)+"个数据包");

            }

            else {

                System.out.println("站点2"+"发送第"+(++b)+"个数据包发生阻塞");

                --b;

            }

            if(al.get(3)!=al.get(0)){

                System.out.println("站点3"+"成功第"+(++c)+"个数据包");

            }

            else {

                System.out.println("站点3"+"发送第"+(++c)+"个数据包发生阻塞");

                --c;

            }

            if(al.get(4)!=al.get(0)){

                System.out.println("站点4"+"成功第"+(++d)+"个数据包");

            }

            else {

                System.out.println("站点4"+"发送第"+(++d)+"个数据包发生阻塞");

                --d;

            }

            if(al.get(5)!=al.get(0)){

                System.out.println("站点5"+"成功第"+(++e)+"个数据包");

            }

            else {

                System.out.println("站点5"+"发送第"+(++e)+"个数据包发生阻塞");

                --e;

            }

           

        for(int i=1;i<6;i++){//当发生冲突的时候,重传,选择重发的时间

            while (al.get(0)==al.get(i)){

                al.set(i, rnd.nextInt(10));

                //compare();

            }

        }

    }

    public void cycle(){

        int sum = a+b+c+d+e;

        for(;sum<=100;){

            sum = a+b+c+d+e;

            change();

        }

    }

}


实验二 网络路由层协议模拟实验

【实验目的和要求】

1.         掌握VB、VC++、VS或JAVA等集成开发环境编写路由仿真程序的方法;

2.         理解并掌握距离向量路由协议和链路状态路由协议的工作原理。

【实验内容】

1.模拟距离向量路由算法的路由表交换过程,演示每轮交换后路由表的变化。

基本要求(动态生成网络拓扑图,节点间的距离随机生成。从初始路由表开始,进行交换路由表,演示每轮交换后的路由表的变化。观察和讨论多少轮交换后路由表稳定)

【实验具体设计实现及结果】

1.  流程图

2.  关键代码说明:

网络动态拓扑图的生成:

for(int j=0;j<linknum;j++){

           int linkname =(int)(Math.random()*(nodenum));//相连节点的名字

           int linkweight =(int)(Math.random()*(nodenum-1)+1);//相连节点的距离

           egnode.linkNode.put(linkname, linkweight);

           }

当然还有许多细节问题需要处理,比如同一两个边之间的距离,保证彼此相连的两个点都在对方的记录之中。

与其邻居节点交换信息:

for(int i=0;i<linkNodeNum;i++){//对所有节点进行遍历

            for( int j=0;j<linkNodeNum;j++){//对某一个节点的相邻节点遍历,记录到这个节点的距离。

               if(arraylist.get(i).linkNode.get(j)!=null){//当与i节点有连接时:

               select(arraylist.get(j).linkNode,i,j);//从其相邻的点中对此当前的点做更新。 

               nn++;

               //System.out.println("第"+((j+1)*(i+1))+"次更新后,路由表的状态");

               System.out.println("第"+nn+"次更新后,路由表的状态");

               for(int test=0;test<arraylist.size();test++){//输出路由表初始化的状态

                  

                   if(arraylist.get(test).linkNode.containsKey(arraylist.get(test).getNodename())){//除去与自身相同的边(即自己与自己相连)

                       arraylist.get(test).linkNode.remove(arraylist.get(test).getNodename());

                   }

                  

                   System.out.println("节点"+arraylist.get(test).getNodename()+

                          "是:"+arraylist.get(test).linkNode.keySet());

                   System.out.println("  距离是:"+arraylist.get(test).linkNode.values());

               }                

            }

       }

      }

3.  实验截图

 

【实验设备与实验环境】

1. 实验设备:联想E430

2. 实验环境:win7家庭版,使用eclipse编写。

【实验总结】

       刚开始由于对于网络路由层次协议不了解而且之前一直在纠结第一个实验。这个实验的进度一直比较慢。在昨天才编写完成。但是通过上网查阅的资料,现在对于网络路由层次协议有了更深的了解。在它路由表的交换过程中,本来是想使用Beelman-Ford算法。但是由于自己的理解能力有限,没法将此算法融入到我的程序中来。可能是数据结构方面出了一些问题。由于时间紧迫,自己编写了路由交换的算法。时间复杂度比较大,但是对于测试的这种小规模问题还是没有很大问题的。但是没有很大的实用性。我需要加强自己的算法。虽然目前写出的程序暂且能够勉强的满足这些功能。可是却是十分蹩脚的功夫。

【源代码】(java编写)

package router_check;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

public class Node {

    private int nodename;

    private int linknum;

    HashSet<Integer> hashset = new HashSet<Integer>(); //到目标节点所需要经过的节点。

    HashMap linkNode = new HashMap(); //相连的目标的节点的属性,名字和距离

    public int getNodename() {

        return nodename;

    }

    public void setNodename(int nodename) {

        this.nodename = nodename;

    }

    public int getLinknum() {

        return linknum;

    }

    public void setLinknum(int linknum) {

        this.linknum = linknum;

    }

    public HashMap getLinkNode() {

        return linkNode;

    }

    public void setLinkNode(HashMap linkNode) {

        this.linkNode = linkNode;

    }

}

package router_check;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.Scanner;

public class Graph {

    ArrayList<Node> arraylist = new ArrayList<Node>();

    Scanner sc = new Scanner(System.in);

    public void init(){

        System.out.println("请输入网络拓扑图中的节点数");

        int nodenum = sc.nextInt();

        for(int i=0;i<nodenum;i++){

            Node egnode = new Node();

            int linknum;       

             egnode.setNodename(i);

             linknum = (int)(Math.random()*(nodenum-1)+1);

             egnode.setLinknum(linknum);

            for(int j=0;j<linknum;j++){

                int linkname =(int)(Math.random()*(nodenum));//相连节点的名字

                int linkweight =(int)(Math.random()*(nodenum-1)+1);//相连节点的距离

                egnode.linkNode.put(linkname, linkweight);

            }

            linknum = egnode.linkNode.size();

            arraylist.add(egnode);

        }

           

        for(int k=0;k<arraylist.size();k++){//除去拓扑图中不必要的 边

            if(arraylist.get(k).linkNode.containsKey(arraylist.get(k).getNodename())){//除去与自身相同的边(即自己与自己相连)

                arraylist.get(k).linkNode.remove(arraylist.get(k).getNodename());

            }

            for(int n=0;n<arraylist.size();n++){//除去可能相连两次的边

                if(arraylist.get(n).linkNode.containsKey(arraylist.get(k).getNodename())

                        &&(arraylist.get(k).linkNode.containsKey(arraylist.get(n).getNodename())))

                {

                    arraylist.get(k).linkNode.put(arraylist.get(n).getNodename(),

                            arraylist.get(n).linkNode.get(arraylist.get(k).getNodename()));

                    arraylist.get(k).linkNode.remove(arraylist.get(n).getNodename());

                }

            }

        }

        //除去初始化是为0的点(实际上不为0)

        for(int no=0;no<arraylist.size();no++){

            if(arraylist.get(no).linkNode.isEmpty()){//如果初始化之后显示节点no的连接为0

                for(int no1=0;no1<arraylist.size();no1++){                 

                        if(arraylist.get(no1).linkNode.get(no)!=null){

                            //若是有其他与此点no相连的点no1,则将no1添加到no中。

                            arraylist.get(no).linkNode.put(no1, arraylist.get(no1).linkNode.get(no));

                        }

                }

            }

        }

       

        //将实际上有连接的点添加到彼此的表之中

        for(int q=0;q<arraylist.size();q++){

            for(int p=0;p<arraylist.size();p++){

                if(arraylist.get(q).linkNode.containsKey(p)==true){

                    //如果在节点q中包含到p的映射,则在节点p中添加到q的距离

                    arraylist.get(p).linkNode.put(q,arraylist.get(q).linkNode.get(p) );

                }

            }

            if(arraylist.get(q).linkNode.containsKey(arraylist.get(q).getNodename())){//除去与自身相同的边(即自己与自己相连)

                arraylist.get(q).linkNode.remove(arraylist.get(q).getNodename());

            }

        }

       

        System.out.println("路由表的初始状态:");

        for(int i=0;i<arraylist.size();i++){//输出路由表初始化的状态

            System.out.println("节点"+arraylist.get(i).getNodename()+

                    "是:"+arraylist.get(i).linkNode.keySet()); 

            System.out.println("  距离是:"+arraylist.get(i).linkNode.values());

        }      

}

}

package router_check;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

public class Table{

    int linkNodeNum;//总共的节点数

    ArrayList<Node> arraylist = new ArrayList<Node>();

    Table(ArrayList<Node> arraylist){

                this.arraylist = arraylist;

    }

    public void createTable(){

        int nn = 0;

        this.linkNodeNum = arraylist.size();

       for(int i=0;i<linkNodeNum;i++){//对所有节点进行遍历

            for( int j=0;j<linkNodeNum;j++){//对某一个节点的相邻节点遍历,记录到这个节点的距离。

                if(arraylist.get(i).linkNode.get(j)!=null){//当与i节点有连接时:

                select(arraylist.get(j).linkNode,i,j);//从其相邻的点中对此当前的点做更新。 

                nn++;

                //System.out.println("第"+((j+1)*(i+1))+"次更新后,路由表的状态");

                System.out.println("第"+nn+"次更新后,路由表的状态");

                for(int test=0;test<arraylist.size();test++){//输出路由表初始化的状态

                   

                    if(arraylist.get(test).linkNode.containsKey(arraylist.get(test).getNodename())){//除去与自身相同的边(即自己与自己相连)

                        arraylist.get(test).linkNode.remove(arraylist.get(test).getNodename());

                    }

                   

                    System.out.println("节点"+arraylist.get(test).getNodename()+

                            "是:"+arraylist.get(test).linkNode.keySet());  

                    System.out.println("  距离是:"+arraylist.get(test).linkNode.values());

                    //printMinNode(arraylist.get(test).hashset);  一种奇怪的现象,暂时还未能完成将其经过最短路径所路过的节点输出

                }                  

            }

       }

      }

    }

   

    public void select(HashMap linkNode,int i,int j){//从与i相连的节点中更新到另外节点j的距离。

        int samllweight = -1;

            for(int n=0;n<linkNodeNum;n++){

                if(linkNode.get(n)!=null){

                   int newWeight = (Integer)linkNode.get(n)+(Integer)arraylist.get(i).linkNode.get(j);

                   //计算i节点经过节点j到n节点的距离

                   if(arraylist.get(i).linkNode.get(n)==null){//如果i节点没有与n节点的距离,更新                 

                       arraylist.get(i).linkNode.put(n, newWeight);//更新到最小距离中

                       arraylist.get(i).hashset.add(j);//更新i节点到目标节点n要经过的节点j

                       //将与i相邻的节点到n节点的距离更新到i

                   }else if(arraylist.get(i).linkNode.get(n)!=null&&

                           ((Integer)arraylist.get(i).linkNode.get(n)>newWeight)){

                      arraylist.get(i).linkNode.put(n, newWeight);//更新到最小距离中

                      arraylist.get(i).hashset.add(j);//更新i节点到目标节点n要经过的节点j

                   }

                       

                }

            }

    }

   

    public void printMinNode(HashSet hashset){//输出最短路径是经过的节点

        Iterator iterator = hashset.iterator();

        while(iterator.hasNext()){

            System.out.print("~"+iterator);

        }

    }

}

package router_check;

public class Test {

    public static void main(String []args){

        Graph graph = new Graph();

        graph.init();

        Table table = new Table(graph.arraylist);

        table.createTable();

    }

}

相关推荐