⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 etherswitch.java

📁 一个小型网络仿真器的实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
   JaNetSim  ---  Java Network Simulator
   -------------------------------------

   This software was developed at the Network Research Lab, Faculty of
   Computer Science and Information Technology (FCSIT), University of Malaya.
   This software may be used and distributed freely. FCSIT assumes no responsibility
   whatsoever for its use by other parties, and makes no guarantees, expressed or
   implied, about its quality, reliability, or any other characteristic.

   We would appreciate acknowledgement if the software is used.

   FCSIT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
   DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING
   FROM THE USE OF THIS SOFTWARE.
*/

package janetsim.component;

import janetsim.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;

public class EtherSwitch extends SimComponent implements SimCommand,AnalyzerUser,
                                            ActionListener,Serializable {
  private class Port implements Serializable {
    SimComponent to_link=null;
    boolean link_busy=false;
    java.util.List outQ=null;
    int outQ_size; //in bytes
    java.util.List spq=null;
    int spq_size; //in bytes
  }

  private class ForwardEntry implements Serializable {
    long dest_mac;
    SimComponent to_link=null;
    //NOTE: for now, no aging is done for the forwarding entries...
  }

  private java.util.Random randgen;

  private SimParamDouble sw_delay;
  private SimParamInt sw_oqsize;
  private SimParamInt sw_spqsize;
  private SimParamInt sw_speed;
  private SimParamDouble sw_ai;
  private SimParamBool sw_name_seed;
  private SimParamInt sw_log_factor;

  private SimParamInt sw_frames_received;
  private SimParamInt sw_dropped;
  private SimParamBool sw_cpucong;

  private java.util.Map sw_forward_table=null;
  private java.util.Map voports;

  private transient Analyzer analyzer=null;

//private events
  static final int MY_RECEIVE = SimProvider.EV_PRIVATE + 1;
  static final int MY_SLOT_TIME = SimProvider.EV_PRIVATE + 2;
  static final int EV_AVERAGING_INTERVAL = SimProvider.EV_PRIVATE + 3;


  public EtherSwitch(String aName,String aClass,Sim aSim,int locx,int locy) {
    super(aName,aClass,aSim,locx,locy);

    randgen=new java.util.Random();

    sw_create();
  }

  public boolean isConnectable(SimComponent comp) {
    if(!super.isConnectable(comp)) return false;

    if(comp.getCompClass().equals("Link")) return true;
    return false;
  }

  protected void neighborAdded(SimComponent comp) {
    Port voport=new Port();
    voport=new Port();
    voport.link_busy=false;
    voport.to_link=comp;
    voport.outQ=new java.util.LinkedList();
    voport.outQ_size=0;
    voport.spq=new java.util.LinkedList();
    voport.spq_size=0;

    voports.put(voport.to_link,voport);
  }

  protected void neighborRemoved(SimComponent comp) {
    voports.remove(comp);
  }

  public void copy(SimComponent comp) {
    if(comp instanceof EtherSwitch) {
      EtherSwitch theComp=(EtherSwitch)comp;
      sw_delay.setValue(theComp.sw_delay.getValue());
      sw_oqsize.setValue(theComp.sw_oqsize.getValue());
      sw_spqsize.setValue(theComp.sw_spqsize.getValue());
      sw_speed.setValue(theComp.sw_speed.getValue());
      sw_ai.setValue(theComp.sw_ai.getValue());
      sw_name_seed.setValue(theComp.sw_name_seed.getValue());
      sw_log_factor.setValue(theComp.sw_log_factor.getValue());
    }
  }

  public Image getImage(Component refcomp) {
    if(image==null) {
      image=Toolkit.getDefaultToolkit().getImage(
                "images"+System.getProperty("file.separator")+"eth_switch.gif");
    }
    return image;
  }

  public void reset() {
    sw_frames_received.setValue(0);
    sw_frames_received.update(theSim.now());
    sw_dropped.setValue(0);
    sw_dropped.update(theSim.now());
    sw_cpucong.setValue(false);
    sw_cpucong.update(theSim.now());

    sw_forward_table.clear();

    java.util.Iterator i=voports.values().iterator();
    while(i.hasNext()) {
      Port voport=(Port)i.next();

      voport.link_busy=false;
      voport.outQ.clear();
      voport.outQ_size=0;
      voport.spq.clear();
      voport.spq_size=0;
    }

    if(analyzer!=null) analyzer.reset();
  }

  public void start() {
    if(sw_name_seed.getValue()==true)
      randgen.setSeed(getName().hashCode());

    for(int i=0;i<randgen.nextInt(100);i++) randgen.nextDouble();

    double aiusec=sw_ai.getValue();
    aiusec+=randgen.nextDouble()*aiusec;
    theSim.enqueue(new SimEvent(EV_AVERAGING_INTERVAL,this,this,
                                theSim.now()+SimClock.USec2Tick(aiusec),null));
  }

  public void action(SimEvent e) {
    switch(e.getType()) {
      case MY_SLOT_TIME:
        sw_proc_slot_time(e);
        break;
      case SimProvider.EV_RECEIVE:
        sw_receive(e);
        break;
      case MY_RECEIVE:
        sw_my_receive(e);
        break;
      case SimProvider.EV_READY:
        sw_ready(e);
        break;
      case EV_AVERAGING_INTERVAL:
        sw_averaging_interval();
        theSim.enqueue(new SimEvent(EV_AVERAGING_INTERVAL,this,this,
                                    theSim.now()+SimClock.USec2Tick(sw_ai.getValue()),null));
        break;
    }
  }


////////////////////////// private methods ////////////////////////////////

  private void sw_create() {
    voports=new java.util.HashMap();
    sw_forward_table=new java.util.HashMap();

    //Initialize the parameters
    long ctick=theSim.now();
    sw_delay=new SimParamDouble("Delay to process a byte (uSec)",this,ctick,false,true,0);
    sw_speed=new SimParamInt("Switching Speed (Mbit/s)",this,ctick,false,true,1000);
    sw_oqsize=new SimParamInt("Output q_size (kbytes, -1=inf)",this,ctick,false,true,100);
    sw_spqsize=new SimParamInt("Speedup q_size (kbytes, -1=inf)",this,ctick,false,true,10);
    sw_ai=new SimParamDouble("Averaging Interval (usec)",this,ctick,false,true,100000.0);
    sw_name_seed=new SimParamBool("Use name as seed",this,ctick,false,true,true);
    sw_log_factor=new SimParamInt("Logging every (ticks) (e.g. 1, 100)",this,ctick,false,true,0);
    sw_frames_received=new SimParamInt("Frames Received",this,ctick,true,false,0);
    sw_frames_received.update(ctick);
    sw_dropped=new SimParamInt("Frames Dropped",this,ctick,true,false,0);
    sw_dropped.update(ctick);
    sw_cpucong=new SimParamBool("CPU Slow Triggered",this,ctick,true,false,false);
    sw_cpucong.update(ctick);

    addParameter(sw_delay);
    addParameter(sw_speed);
    addParameter(sw_oqsize);
    addParameter(sw_spqsize);
    addParameter(sw_ai);
    addParameter(sw_name_seed);
    addParameter(sw_log_factor);
    addParameter(sw_frames_received);
    addParameter(sw_dropped);
    addParameter(sw_cpucong);
  }

  private void sw_averaging_interval() {
    //nothing here for now...
  }

  private void sw_proc_slot_time(SimEvent e) {
  //performing the demux_spq operation

    Port voport=(Port)e.getParams();
    EtherFrame frame;
    long ticks;

    //check for cpu congestion (just mark it, no action taken)
    if(voport.spq_size > (sw_spqsize.getValue()*1024)) {
      sw_cpucong.setValue(true);
      sw_cpucong.update(theSim.now());
    }

    //voport.spq must not be empty here!
    if(voport.spq.isEmpty()) {
      System.out.println("Warning: sw_proc_slot_time called with spq empty!!");
      return;
    }

    frame=(EtherFrame)voport.spq.remove(0);
    voport.spq_size -= (frame.length()>>3);

    if((voport.outQ_size + (frame.length()>>3) < sw_oqsize.getValue() * 1024)
      || (sw_oqsize.getValue() == -1)) {
      voport.outQ.add(frame);
      voport.outQ_size += (frame.length() >> 3);
    }
    else {
      sw_dropped.setValue(sw_dropped.getValue()+1,theSim.now(),sw_log_factor.getValue());
      frame=null;
    }

  //output frame to link if possible
    if(!voport.outQ.isEmpty() && !voport.link_busy) {
      voport.link_busy=true;
      sw_schedule_output(voport);
    }

  //schedule next proc_slot if needed
    if(!voport.spq.isEmpty()) {
      frame=(EtherFrame)voport.spq.get(0);
      ticks=SimClock.USec2Tick(frame.length() / (double)sw_speed.getValue());
      theSim.enqueue(new SimEvent(MY_SLOT_TIME,this,this,theSim.now()+ticks,voport));
    }
  }

  private void sw_ready(SimEvent e) {
    Port voport=(Port)voports.get(e.getSource());
    if(voport!=null) {
      if(voport.link_busy) {
        voport.link_busy=false;
        if(!voport.outQ.isEmpty()) {
          voport.link_busy=true;
          sw_schedule_output(voport);
        }
      }
    }
  }

  private void sw_schedule_output(Port voport) {
    EtherFrame frame=(EtherFrame)voport.outQ.remove(0);
    voport.outQ_size -= (frame.length()>>3);

    theSim.enqueue(new SimEvent(SimProvider.EV_RECEIVE,this,
                                voport.to_link,theSim.now(),frame));

    //inform analyzer
    if(analyzer!=null) analyzer.update(frame,this,voport.to_link);
  }

  private void sw_receive(SimEvent e) {
    EtherFrame frame=(EtherFrame)e.getParams();
    SimComponent src=(SimComponent)e.getSource();
    long ticks;

    ticks=SimClock.USec2Tick(sw_delay.getValue() * (frame.length()>>3));
    theSim.enqueue(new SimEvent(MY_RECEIVE,src,this,
                        theSim.now()+ticks,e.getParams()));

    //update frames count
    sw_frames_received.setValue(sw_frames_received.getValue()+1,theSim.now(),sw_log_factor.getValue());

    //inform analyzer
    if(analyzer!=null) analyzer.update(frame,src,this);
  }

  private void sw_broadcast(EtherFrame frame,SimComponent src) {
    long ticks;

    java.util.Iterator i=voports.values().iterator();
    while(i.hasNext()) {
      Port voport=(Port)i.next();
      if(voport.to_link==src) continue; //skip the source port

      voport.spq.add(frame);
      voport.spq_size+= (frame.length()>>3);

      if(voport.spq.size()==1) { //must schedule a processing slot if spq previously empty
        ticks=SimClock.USec2Tick(frame.length() / (double)sw_speed.getValue());
        theSim.enqueue(new SimEvent(MY_SLOT_TIME,this,this,theSim.now()+ticks,voport));
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -