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

📄 simulator.java

📁 source code for fishnet
💻 JAVA
字号:
import java.io.InputStreamReader;import java.io.BufferedReader;import java.io.IOException;import java.io.FileNotFoundException;import java.lang.reflect.Method;/** * <pre>    * Manages a simulation. All nodes are instantiated in process. * </pre>    */public class Simulator extends Manager {        public static final int MAX_NODES_TO_SIMULATE = Packet.MAX_ADDRESS - 1;        private long now;  // simulated time in microseconds    private double timescale;    private Node[] nodes;        private SimulationCommandsParser topoFileParser;    private IOThread ioThread;    /**     * Creates a new simulation     * @param numNodes The number of nodes to simulate     * @param topoFile The name of the topology file to use     * @throws IllegalArgumentException If the number of nodes to simulate is < 0 or > MAX_NODES_TO_SIMULATE     * @throws FileNotFoundException If the given topology file cannot be found     */    public Simulator(int numNodes, String topoFile) throws IllegalArgumentException, FileNotFoundException {	super(0);	super.setParser(new SimulationCommandsParser(this));	if(numNodes <= 0 || numNodes > MAX_NODES_TO_SIMULATE) {	    throw new IllegalArgumentException("Invalid number of nodes given to simulate. Nodes given: " + numNodes);	}	this.now = 0;	this.timescale = 1.0;	this.nodes = new Node[numNodes];	for(int i = 0; i < numNodes; i++) {	    this.nodes[i] = new Node(this, i);	}		this.topoFileParser = new SimulationCommandsParser(this);		long deferTill = this.topoFileParser.parseFile(topoFile, this.now);	this.addEvent(deferTill, "parseRestOfTopoFile", this, null, null);	this.ioThread = new IOThread();	this.ioThread.start();    }        /**     * Starts the simulation     */    public void start() {	// Start all the nodes	for(int i = 0; i < this.nodes.length; i++) {	    this.nodes[i].start();	}	this.now = 1;		Event nextEvent;	long waitTime; // time in microseconds	long deferParsingTill = 0;		while(true) {	    long deltaTime = 0;	    deferParsingTill = this.readFishFile(deferParsingTill);	    nextEvent = null;	    waitTime = -1;  // wait indefinitely	    if(!this.sortedEvents.isEmpty()) {		nextEvent = this.sortedEvents.getNextEvent();		deltaTime = nextEvent.timeToOccur() - this.now;				waitTime = 0; // Don't wait for user input. If delta time > 0 then will get reset below		 	    }else if(deferParsingTill >= 0) {		deltaTime = deferParsingTill - this.now;		waitTime = 0;	    }	    if(deltaTime > 0 && this.timescale > 0) {		waitTime = (long)(((double)deltaTime) / this.timescale);   	    }	    	    long beforeInputTime = Utility.fishTime();	    String userInput = this.getUserInput(waitTime);	    	    // Process user input if there is any	    if(userInput != null) {		// Increment now		this.now += (long)((Utility.fishTime() - beforeInputTime) * this.timescale);		    		this.parser.parseLine(userInput, this.now);	    }else {		// Have waited appropriate amount of real time, so can fast-forward now		this.now = Math.max(this.now, deltaTime + this.now);				// Run all pending events		while((nextEvent != null) && (nextEvent.timeToOccur() <= this.now)) {		    this.sortedEvents.removeNextEvent();		    try {			nextEvent.callback().invoke();		    }catch(Exception e) {			System.err.println("Exception while trying to invoke method in Simulator. Error: " + e);			e.printStackTrace();		    }		    nextEvent = this.sortedEvents.getNextEvent();		}	    }	    	}    }    /**     * Send the pkt to the specified node     * @param from The node that is sending the packet     * @param to Int spefying the destination node     * @param pkt The packet to be sent, serialized to a byte array     * @return True if the packet was sent, false otherwise     * @throws IllegalArgumentException If the arguments are invalid     */    public boolean sendPkt(int from, int to, byte[] pkt) throws IllegalArgumentException {	super.sendPkt(from, to, pkt);  // check arguments	Edge edge;	if(to == Packet.BROADCAST_ADDRESS) {	    for(int i = 0; i < this.nodes.length; i++) {		edge = Topology.GetInstance().getLiveEdge(from, i);		if(edge != null) {		    this.deliverPkt(i, this.nodes[i], from, pkt, edge);		}				//this.nodes[from].onReceive(from, pkt);  // Should the node that broadcast also receive the pkt?	    }	}else if((edge = Topology.GetInstance().getLiveEdge(from, to)) != null) {	    this.deliverPkt(to, this.nodes[to], from, pkt, edge);	}else {	    System.err.println("Failed to send pkt from: " + from + " to: " + to);	    return false;	}	return true;    }    /**     * Retrieve current time in milliseconds     * @return Current time in milliseconds     */    public long now() {	return this.now / 1000;    }        /**     * Adds a timer to be fired at time t     * @param nodeAddr Addr of node that is registering this timer     * @param t The time when the timer should fire. Its in milliseconds     * @param callback The callback to be invoked when the timer fires     */    public void addTimerAt(int nodeAddr, long t, Callback callback) {	if( (!this.isNodeAddrValid(nodeAddr)) ) {	    return;	}		super.addTimerAt(nodeAddr, t, callback);    }    /**     * Sends the msg to the the specified node      * @param nodeAddr Address of the node to whom the message should be sent     * @param msg The msg to send to the node     * @return True if msg sent, false if address is not valid     */    public boolean sendNodeMsg(int nodeAddr, String msg) {	if(!this.isNodeAddrValid(nodeAddr)) {	    return false;	}	this.nodes[nodeAddr].onCommand(msg);	return true;    }        /**     * Sets the amount to scale real time by.     * @param timescale The amount to scale real time by     */    public void setTimescale(double timescale) {	this.timescale = timescale;    }    /**     * Parses rest of topology file. Has public accesibility since used as a callback     */    public void parseRestOfTopoFile() {	long deferTill = this.topoFileParser.parseRemainder(this.now);	this.addEvent(deferTill, "parseRestOfTopoFile", this, null, null);	    }    /******************** Private Functions ********************/    private boolean isNodeAddrValid(int nodeAddr) {	return ((nodeAddr >= 0) && (nodeAddr < this.nodes.length));    }	    private void deliverPkt(int destAddr, Node destNode, int srcAddr, byte[] pkt, Edge edge) {	long timeToDeliver = edge.schedulePkt(srcAddr, pkt.length, this.now);	if(timeToDeliver == -1) {	    return;  // pkt dropped	}		String[] paramTypes = {"java.lang.Integer", "[B"};	Object[] params = {new Integer(srcAddr), pkt};	this.addEvent(timeToDeliver, "onReceive", destNode, paramTypes, params);	    }    private String getUserInput(long timeout) {	if (timeout == 0) {	    return null;	}	timeout = Math.max(timeout, 0);	long endTime = (this.now() * 1000) + timeout;	try {	    // Test for condition in while loop in case of spurious wakeup	    while(this.ioThread.isEmpty() && Utility.fishTime() < endTime) {		synchronized(this.ioThread) {		    this.ioThread.wait(timeout / 1000);		}	    }	 }catch(InterruptedException e) {	    // Do nothing. This should never happen, even if it does no harm done	}		return this.ioThread.readLine();    }}

⌨️ 快捷键说明

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