java模拟网桥功能_目的地址

1.host主机类

package FirstExpriment;

import java.util.HashMap;
import java.util.Map;

/**
* 模拟主机功能
* 属性:端口号,物理地址
* 函数作用:协助交换表的广播的查询、增加记录等
*/
public class Host {
private String port;
private String mac;

// 交换机使用的交换表,以目的地址mac为key,以端口地址port+时间date的数组为value
public static Map<String,String>hostMap =new HashMap<>();

public Host(String mac,String port){
this.port =port;
this.mac =mac;
hostMap.put(mac,port);
}

/* 转发帧:
查找交换表中与收到帧的目的地址有无相匹配的项目。
如没有,则向所有其他接口(进入的接口除外)转发。
如有,则按交换表中给出的接口进行转发。
若交换表中给出的接口就是该帧进入交换机的接口,则应丢弃这个帧(因为这时不需要经过交换机进行转发)。
*/
public static void receiveBroadcast(String src,String dest){
if(src==null||dest==null) return; //判空
for(Map.Entry<String ,String> entry : hostMap.entrySet()){
String curMac = entry.getKey();
String curPort = entry.getValue();//当前端口
//若交换表中给出的接口就是该帧进入交换机的接口,则应丢弃这个帧,该帧不对该地址广播源地址
if(src.equals( curMac) ) continue;
//如果目的地址相同,收下该帧
if(dest.equals(curMac)){
System.out.println("地址"+curMac+"通过"+curPort+"接口收下了该帧");
}else{
System.out.println(curPort+"接口丢弃了该帧" ) ;
}
}
}
}

2、交换机类

package FirstExpriment;

import java.util.HashMap;
import java.util.Map;
import java.text.SimpleDateFormat;

/**
* 交换表作用
*/
public class exchangeMachine {
private Map<String ,String[]>exchangeTable =null;
public exchangeMachine(){
exchangeTable =new HashMap();
}
//传输帧
public void transferFrame(String frame){
String segment[];
segment = frame.split(" ");
//frame 格式: destMac srcMac information
String destMac = segment[0];
String srcMac = segment[1];
// 这里注释的是,模拟黑客通过接口窃取用户信息
// String information="";
// for(int i=3;i<segment.length-1;i++){
// information += segment[i];
// }
boolean isSrcExit =false;
boolean isDestExit =false;
//查找交换表
for(Map.Entry<String ,String[]> entry:exchangeTable.entrySet()){
String curMac =entry.getKey();
if(srcMac.equals(curMac)){
isSrcExit=true;//源地址存在
}
if(destMac.equals(curMac)){
isDestExit =true;//目的地址存在
}
if(isDestExit && isSrcExit) //源地址和目的地址都在交换表中存在
break;
}
// 源地址不在交换表中,需要加入交换表
// 源地址在交换表中,则需要更新交换表中对应的进入接口和有效时间
addAndUpdateExchangeTable(srcMac,isSrcExit) ;
if(isDestExit)//目的地址存在
System.out.println("查找到目的地址"+destMac+",直接转发信息");
else//目的地址不存在表,需要广播
Host.receiveBroadcast(srcMac,destMac);
}
private void addAndUpdateExchangeTable(String srcMac,boolean isSrcExit){
for(Map.Entry<String ,String>entry: Host.hostMap.entrySet() ){
String curMac = entry.getKey();
String curPort = entry.getValue();//当前端口
if(srcMac.equals(curMac)){
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
String date = df.format(System.currentTimeMillis());
exchangeTable.put(curMac,new String[]{curPort,date});
if(!isSrcExit)
System.out.println("源目的Mac地址为"+srcMac +",通过"+curPort+"端口"+"加入了交换表中,加入的有效时间为"+date);
else
System.out.println("源目的Mac地址为"+srcMac +",通过"+curPort+"端口"+"加入了交换表中,更新加入的有效时间为"+date);
break;
}
}
}



}

3、网桥类

package FirstExpriment;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* 读取的文件是按行读取,且每一行的格式必须是
* 目的地址(6字节) 源地址(6字节) 类型(2字节) IP数据报(46-1500字节) fcs(4字节)
* 毕竟是模拟,所以只是按照格式,忽略真实字节数
* destinaionMac sourceMac 0x0800 content FCS
*/
public class netBridge {
public final static String inFilePath1 ="C:\\Users\\Lenovo\\Desktop\\1.txt";
public final static String inFilePath2 ="C:\\Users\\Lenovo\\Desktop\\2.txt";
public static void main(String args[]) throws IOException {
BufferedReader reader1=null;
BufferedReader reader2= null;
//需要声明几台主机,确定实验环境,文件中目的地址和源地址只有在这几个的范围内才可以,(按序生成端口号和mac地址,考虑100个内)
Host hosts[]=new Host[4];
//初始化主机
initHosts(hosts);
exchangeMachine table =new exchangeMachine();
try {
reader1 = new BufferedReader(new InputStreamReader(new FileInputStream(inFilePath1), "UTF-8"));
reader2 = new BufferedReader(new InputStreamReader(new FileInputStream(inFilePath2), "UTF-8"));
String frame;
while (true) {
if ((frame = reader1.readLine()) != null && !frame.equals("") )
tableTransferFrame(table,frame);
else {
while ((frame = reader2.readLine()) != null && !frame.equals(""))
tableTransferFrame(table,frame);
break;
}
if ((frame = reader2.readLine()) != null && !frame.equals(""))
tableTransferFrame(table,frame);
else {
while ((frame = reader1.readLine()) != null && !frame.equals(""))
tableTransferFrame(table,frame);
break;
}
}
}
catch(Exception e){
e.printStackTrace();
}
finally{
reader1.close();
reader2.close();
}
}

public static void initHosts(Host hosts[]){
int length=hosts.length;
//主机的MAC地址
String hostName[] =new String[length];
//主机的端口号
String portName[]=new String[length];
for(int t=0;t<length;t++){
if(t<10) {
hostName[t] = "E8-2A-44-E8-E5-0" + t;
portName[t] = "000"+t;
}else{
hostName[t] = "E8-2A-44-E8-E5-"+t;
portName[t] = "00"+t;
}
//初始化每台主机
hosts[t]=new Host(hostName[t],portName[t]);
}

}
private static void tableTransferFrame(exchangeMachine table, String frame){
table.transferFrame(frame);
System.out.println();
}
}

4、测试案例:

文件1内容:
E8-2A-44-E8-E5-01 E8-2A-44-E8-E5-00 0x0800 hello world fcs
E8-2A-44-E8-E5-02 E8-2A-44-E8-E5-02 0x0800 你好世界+1 fcs
E8-2A-44-E8-E5-01 E8-2A-44-E8-E5-00 0x0800 hello world+1 fcs
文件2内容:
E8-2A-44-E8-E5-03 E8-2A-44-E8-E5-00 0x0800 你好世界 fcs
E8-2A-44-E8-E5-03 E8-2A-44-E8-E5-01 0x0800 hello world+1 fcs
E8-2A-44-E8-E5-00 E8-2A-44-E8-E5-00 0x0800 你好世界+1 fcs
E8-2A-44-E8-E5-02 E8-2A-44-E8-E5-00 0x0800 你好世界+2