//Title: Cprobing Measurement for available network bandwidth //Version: //Copyright: Copyright (c) 1998 //Author: xhe //Company: UCCS package Simulator; import javax.swing.*; import java.io.*; import java.util.*; import java.lang.Runnable; public class CprobingMeasurement extends Measurement implements Runnable { public CprobingMeasurement(JPanel ch,String trafficpattern,double smt,double emt,double tmi, double pmi, boolean trafficoutput) { try { super.ThreadInit(ch,trafficpattern,smt,emt,tmi,pmi,trafficoutput); jbInit(); } catch (Exception e) { e.printStackTrace(); } } private void jbInit() throws Exception { // initilize the newwork topology based on configure file StringTokenizer t; Double DTemp; EQ = new EventsQueue(); try { BufferedReader ifile = new BufferedReader(new FileReader("configure.txt")); String s; int iterate=0; // first line for four parameters of PInternalTime, PBIntervalTime // TInternalTime and TBIntervalTime // we get them in the parent class of Measurement s = ifile.readLine(); // skip the first line // second line for five number: how many Router, Link and Road, // the fourth number is the number of the bottleneck Link // the fifth number is the number of how many probing message in one probing route s = ifile.readLine(); t = new StringTokenizer(s,"|"); numOfRouter = Integer.parseInt(t.nextToken()); numOfLink = Integer.parseInt(t.nextToken()); numOfRoad = Integer.parseInt(t.nextToken()); Routers = new Router[numOfRouter+1]; Links = new Link[numOfLink+1]; RoadTable = new RouterTable[numOfRoad]; // generate all the routers: range starts from 1 for(int i=1; i<= numOfRouter; i++) Routers[i] = new Router(this,i); // generate all the links: range starts from 1 for(int i=1; i<= numOfLink; i++) { //int distance = rnd.nextInt(1000)+3; // a random link distance; Links[i] = new Link(this,100000,i); } BottleneckLink = Links[Integer.parseInt(t.nextToken())]; BottleneckLink.BottleneckLink = true; // set the field // retrieve how many messages needed in one Cprobing cycle CprobingNum = Integer.parseInt(t.nextToken()); // create the router table, start from 0 // each line after third line(included) is a single road table while (iterate < numOfRoad) { s = ifile.readLine(); t = new StringTokenizer(s,"|"); int RoadNodeNum = t.countTokens(); RoadTable[iterate] = new RouterTable(iterate,RoadNodeNum); int num=0; String tmp; while (num < RoadNodeNum){ tmp = t.nextToken(); if (tmp.charAt(0) == 'L') // this is a link object RoadTable[iterate].append(Links[Integer.parseInt(tmp.substring(1))],num); else RoadTable[iterate].append(Routers[Integer.parseInt(tmp.substring(1))],num); num++; } // end of one single line, inner while iterate ++; } // end of all road table, outer while ifile.close(); } catch (IOException d) { System.out.print("Error" + d); System.exit(1); } // open a log file for the writing of simulator try { LogFile = new PrintWriter(new FileWriter("log.txt")); PFile = new PrintWriter(new FileWriter("probing.txt")); //EventFile = new PrintWriter(new FileWriter("Events.txt")); } catch(IOException k) { System.out.print("Error" + k); System.exit(1); } } public void run() { // there is only one probing agent. // The first router of the first road is the probing agent. // the first router in each of the rest roads is the traffic generation agent. Message M,NewM; double Start_TrafficTime = 0.1; //double Start_TrafficTime = 6.0; // initializing the start event // for the probing agent // generate the initial probing message, size is static value 46 bytes M = new Message(0,0,"Cprobe-start",46*8,Start_MeaTime); // the message nubmer is useless. //M = new Message(0,0,"Probe-start",46*8,0); // the message nubmer is useless. EQ.insert(M); if (traffic.trafficType.equals("Web")) { // web traffic pattern M = new Message(0,1,"New-WebMess",46*8,Start_TrafficTime); pareto = new Pareto(); weibull = new Weibull(); } else { // for flat/slope traffic pattern // Generate the first "Traffic-start" type message // always the first traffic agent is to use it to set the bottleneck M = new Message(0,1,"Traffic-start",46*8,Start_TrafficTime); } EQ.insert(M); // generate the last "Simulation-end" message // all arguments except the data type are useless. M = new Message(0,0,"Simulation-end",8,end_time); EQ.insert(M); int MessSize = 500*8; // message size is 1000 bytes double SendingTime=0.0; // the start sending time of the current Cprobing cycle // start event dispatching while ((M = EQ.nextItem()) != null) { boolean flag = false; String MessageType = M.MessageType; if (MessageType.compareTo("Simulation-end") == 0) { PFile.close(); LogFile.close(); // close all the opened file in Router for(int i=1; i<= numOfRouter; i++) Routers[i].OFILE.close(); // close all the opened file in Link for(int i=1; i<= numOfLink; i++) Links[i].OFILE.close(); //EventFile.close(); return; } if (MessageType.compareTo("Traffic-start") == 0) { // there is only one Traffic-start message, it starts generating general traffic // generate a new traffic message // the message type is "HTTP-request" NewM = new Message(++MaxMessNum,M.RouterTableNum,"HTTP-request",traffic.TrafficMessSize,M.getArrivalTime()); RoadTable[NewM.RouterTableNum].Node(NewM.NextObjectIndex).EventHandler(NewM); EQ.insert(NewM); BottleneckLink.Tstarting_time = M.getArrivalTime(); BottleneckLink.Transfered_bit = 0; // a new measure cycle BottleneckLink.end_time = M.getArrivalTime()+TBIntervalTime; // change M type to a new traffic generation message: "New-TrafficMess" // wakeup me to generate the next traffic message in one traffic route // message number is useless. M.MessageType = "New-TrafficMess"; M.setTime(M.getArrivalTime()+TInternalTime); EQ.insert(M); flag = true; } if (!flag && (MessageType.compareTo("New-TrafficMess") == 0)) { // traffic agent generates a new traffic message // generate the next traffic message generation message // generate a new traffic message // change the message type to "HTTP-request" //NewM = new Message(++MaxMessNum,M.RouterTableNum,"HTTP-request",(rnd.nextInt(2400)+100)*8,M.getArrivalTime()); ++MaxMessNum; NewM = new Message(MaxMessNum,M.RouterTableNum,"HTTP-request",traffic.TrafficMessSize,M.getArrivalTime()); //NewM = new Message(++MaxMessNum,M.RouterTableNum,RoadTable[M.RouterTableNum].numOfNode, // M.getArrivalTime(),"HTTP-request",(rnd.nextInt(1900)+100)*8,M.getArrivalTime()); RoadTable[NewM.RouterTableNum].Node(NewM.NextObjectIndex).EventHandler(NewM); EQ.insert(NewM); // set next "New-TrafficMess" generation time // wakeup me to generate the next new traffic message M.setTime(M.getArrivalTime()+TInternalTime); EQ.insert(M); flag = true; } if (!flag && (MessageType.compareTo("Cprobe-start") == 0)) { // probing agent generates a couple of Cprobing Message // set the next Cprobing Measurement start time // probing message number always from 1 to CprobingNum SendingTime = M.getArrivalTime(); // the start sending time of the current Cprobing cycle double NextSendingTime = M.getArrivalTime(); // A new Cprobing cycle starts for (int j=1; j<=CprobingNum;j++) { // generate the Cprobing mess NewM = new Message(j,M.RouterTableNum,RoadTable[M.RouterTableNum].numOfNode, SendingTime,"CP-request",MessSize,NextSendingTime,0,UnitripProbe); RoadTable[NewM.RouterTableNum].Node(NewM.NextObjectIndex).EventHandler(NewM); EQ.insert(NewM); NextSendingTime = NewM.getArrivalTime(); } // generate the next "Cprobing-start" message M.setTime(M.getArrivalTime()+PBIntervalTime); EQ.insert(M); flag = true; } if (!flag && (MessageType.compareTo("New-WebMess") == 0)) { double AT = M.getArrivalTime(); // generate a new web request message: "HTTP-request" NewM = new Message(++MaxMessNum,M.RouterTableNum,"HTTP-request",46*8,AT); RoadTable[NewM.RouterTableNum].Node(NewM.NextObjectIndex).EventHandler(NewM); EQ.insert(NewM); BottleneckLink.Tstarting_time = M.getArrivalTime(); BottleneckLink.Transfered_bit = 0; // a new measure cycle BottleneckLink.end_time = M.getArrivalTime()+TBIntervalTime; // reset the next web message generation time // the time is conform to pareto distribution double Fx = rnd.nextDouble(); double lowerBound = 1.0; double alpha = 1.5; double gap = pareto.getX(Fx,lowerBound,alpha); M.setTime(AT+gap); EQ.insert(M); flag = true; } if (!flag && (MessageType.compareTo("HTTP-request") == 0)) { // wakeup the corresponding object to handle this message // set the wakeup time of the message next time. boolean responseMess_GetToDestination = RoadTable[M.RouterTableNum].Node(M.NextObjectIndex).EventHandler(M); if (!responseMess_GetToDestination) EQ.insert(M); flag = true; } // "HTTP-response" message type is only shown up in Web traffic pattern if (!flag && (MessageType.compareTo("HTTP-response") == 0)) { // wakeup the corresponding object to handle this message // set the wakeup time of the message next time. //double old_ArrivalTime = M.getArrivalTime(); boolean responseMess_GetToDestination = RoadTable[M.RouterTableNum].Node(M.NextObjectIndex).EventHandler(M); if (!responseMess_GetToDestination) EQ.insert(M); // The response message does not back to its source flag = true; } if (!flag && (MessageType.compareTo("CP-request") == 0)) { // wakeup the corresponding object to handle this message // set the wakeup time of the message next time. NewM = new Message(M.MessNum,M.RouterTableNum,RoadTable[M.RouterTableNum].numOfNode, SendingTime,"CP-request",MessSize,M.getArrivalTime(),M.NextObjectIndex,UnitripProbe); RoadTable[NewM.RouterTableNum].Node(NewM.NextObjectIndex).EventHandler(NewM); EQ.insert(NewM); flag = true; } if (!flag && (MessageType.compareTo("CP-response") == 0)) { // wakeup the corresponding object to handle this message // set the wakeup time of the message next time. //double old_ArrivalTime = M.getArrivalTime(); NewM = new Message(M.MessNum,M.RouterTableNum,RoadTable[M.RouterTableNum].numOfNode, SendingTime,"CP-response",MessSize,M.getArrivalTime(),M.NextObjectIndex,UnitripProbe); boolean responseMess_GetToDestination = RoadTable[NewM.RouterTableNum].Node(NewM.NextObjectIndex).EventHandler(NewM); if (!responseMess_GetToDestination) EQ.insert(NewM); // The response message does not back to its source else { if (NewM.MessNum == CprobingNum) { // the last one return double Measued_Band = (MessSize * CprobingNum) / (NewM.getArrivalTime() - NewM.Pstarting_time); LogFile.println("CProbing start Time: "+ M.Pstarting_time + " End Time: " + M.getArrivalTime() + " Measured BandWidth: "+ Measued_Band); final double time = M.getArrivalTime(); final double band = Measued_Band*10/LinkBandwidth; Runnable updateJPanel = new Runnable() { public void run() { chart.JPanelUpdate(4,time,band); } }; SwingUtilities.invokeLater(updateJPanel); } } // end of if } EQ.remove(); // remove the first message from the event queue } // end of while } public void UpdateLog (double output_time) { if (output_time >= Start_MeaTime) { // update the chart double Available_BandWidth = LinkBandwidth - (BottleneckLink.Transfered_bit/TBIntervalTime); LogFile.println("Starting Time: "+ BottleneckLink.Tstarting_time + " End Time: " + output_time + " Available BandWidth: "+ Available_BandWidth+" | " + BottleneckLink.Transfered_bit); if (trafficoutput) { final double time = output_time; final double band = Available_BandWidth*10/LinkBandwidth; Runnable updateJPanel = new Runnable() { public void run() { chart.JPanelUpdate(2,time,band); } }; SwingUtilities.invokeLater(updateJPanel); } } traffic.ArguChange(output_time > Start_MeaTime); } }