写一个程序来模拟网桥功能。

一、实验内容

模拟实现网桥的转发功能,以从文件中读取帧模拟网桥从网络中收到一帧,即从两个文件中读入一系列帧,从第一个文件中读入一帧然后从第二个文件中再读入一帧,如此下去。对每一帧,显示网桥是否会转发。

要求:

Windows或Linux环境下运行,程序应在单机上运行。

分析:

用程序模拟网桥功能,可以假定用两个文件分别代表两个网段上的网络帧数据。而两个文件中的数据应具有帧的特征,即有目的地址,源地址和帧内数据。程序交替读入帧的数据,就相当于网桥从网段中得到帧数据,当然如果模拟的数据量比较少,也可以用两个数组代替两个文件存放帧数据,同样达到代表两个网段上的帧数据的效果。对于网桥来说,能否转发帧在于把接收到的帧与网桥中的转发表相比较。判断目的地址后才决定是否转发。由此可见转发的关键在于构造转发表。这里转发表可通过动态生成。

二、程序流程图

在这里插入图片描述

三、参考代码

package bridge;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Scanner;

public class Bridge {

	@SuppressWarnings("unused")
	public static void main(String[] args) {
		try(FileReader f1 = new FileReader("f1.txt");
			    BufferedReader br1 = new BufferedReader(f1);	
				FileReader f2 = new FileReader("f2.txt");
				BufferedReader br2 = new BufferedReader(f2)) {
			
			Bridge bridge = new Bridge();
			Frame frame = bridge.new Frame();
			while(br1 != null || br2 != null) { 
				if(br1 != null ) {
					frame.dstmac = br1.readLine();
					frame.srcmac = br1.readLine();
					if(frame.dstmac != null && frame.srcmac !=null) {
						bridge.rec(frame, "m0");
					}else {
						break;
					}
					
				}else {
					f1.close();
				}
			
				if(br2 != null) {
					
					frame.dstmac = br2.readLine();
					frame.srcmac = br2.readLine();
					if(frame.srcmac != null && frame.dstmac != null) {
						
						bridge.rec(frame, "m1");
					}else {
						break;
					}
				
					
				}else {
					f2.close();
				}
			}	
		}catch(Exception e) {
			e.printStackTrace();
		}
}	
	
	 int max = 128;
	static int num = 0; 
	 String[][] table = new String[max][2];  //转发表:[地址][接口]
	
	 class Frame{			
	 String dstmac;     //目的mac地址
     String srcmac;     //源mac地址			
    }
	
	  void show() {
		System.out.println("\t地址\t\t接口");
		int i,j;
		for(i=0;i<max-1;i++)
		{
			for(j=0;j<2;j++) {
				if(table[i][j] != null) {
					System.out.print(table[i][j]+"\t");
				}
			} 
			
			System.out.println();	
			if(table[i][1] == null) break;
			
		}
		System.out.println("------------------------------------------");
	}
	 
	  int srcinside(Frame frame) {    //判断源mac地址是否在转发表内,自学习 
	 	int i;
	 	for(i=0;i<=num;i++)
	 	{
	 		if(frame != null && frame.srcmac.equals(table[i][0])) return 1;  //在内
	 	}
	 	return 0;   //不在
	 }
	 
	  int dstinside(Frame frame)   //判断目的mac地址是否在转发表内
	 {
	 	int i;
	 	for(i=0;i<=num;i++)
	 		if(frame != null && frame.dstmac.equals(table[i][0])) return i; //返回记录行
	 	return -1;    //不在
	 }
	 
	  void update(Frame frame, String inter)
	 {
	 	table[num][0] = frame.srcmac;  //添加地址
	 	table[num][1] = inter;    //添加接口
	 	num++;
	 }
	 
	  void rec(Frame frame,String inter){
	 	if(frame.srcmac != null && frame.dstmac != null) {

			 System.out.println("从"+inter+"接口收到的帧,源地址为:"+frame.srcmac+",目的地址:"+frame.dstmac);
		 	if(dstinside(frame) == -1) {
		 		
		 		System.out.println("转发表内无该条目!从除"+inter+"的其余接口转发!");
		 		
		 		if(srcinside(frame) == 0) {
		 			
		 			update(frame, inter);  //自学习
		 		}
		 	}
		 	else {
		 		if(srcinside(frame) == 0) update(frame, inter);  //自学习
		 		
		 		System.out.print("转发表内找到匹配条目!");
		 		
		 			if(table[dstinside(frame)][1] == inter ) {
		 				
		 				System.out.println("由于在同一个接口,直接丢弃!");
		 			}	 			
		 				
		 			else {
		 				
		 				System.out.print("从"+table[dstinside(frame)][1]+"接口转发!");
		 				System.out.println();
		 			}
		 				
		 	}

		 	show();

	 	}
	 }		

}

四、运行结果

在这里插入图片描述

五、总结

首先先设置一个二维字符串数组作为转发表,转发表内容包括地址以及转发接口。其次,建立一个帧结构,帧内容包括:目的mac地址、源mac地址。最后,在实现的时候,为了编程简单和便于理解,文件中设置了帧的目的mac地址和源mac地址为一个字母。就通过不断从文件中交替,每次读取两行数据,与转发表进行比较。若转发表存在,则判断目的mac地址是否与源mac地址,是否在同一接口,相同则丢弃,不同则转发。若转发表不存在,则通过自学习,简单地将源mac地址和接口信息记录到转发表内,并转发到其他接口。

猜你喜欢

转载自blog.csdn.net/qq_41900081/article/details/85275453