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