//Title: Single Message Measurement for available network bandwidth //Version: //Copyright: Copyright (c) 1998 //Author: xhe //Company: UCCS package Simulator; //import java.awt.*; //import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.*; import java.lang.Runnable; public class MultipleMessMeasurement extends Measurement implements Runnable { double RoundTripTime; int MultipleMessNum; public MultipleMessMeasurement(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 six numbers: how many Router, Link and Road, // the fourth number is the link NO of the bottleneck Link // the fifth number is the number of how many probing message in one probing route // the sixth number is how many single messages 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()); // how many messages needed in one probing route. MultipleMessNum = 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.3; //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,"Probe-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); // Generate one "RoundTripTime-Probing" type messages // to measure the relatively accurate round trip time for a message // the probing agent sends this type message always. // This probing message is declared with traffic message constructor // because the queuing time at each object of its route is 0.0 M = new Message(0,0,"RoundTripTime-ProbingRequest",46*8,0.0); M.MessMeasurementType = UnitripProbe; //M = new Message(0,0,"RoundTripTime-ProbingRequest",46*8,6.0); 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); double MBW = 0; // the sum of single measured bandwidth in one probing route // 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("RoundTripTime-ProbingRequest") == 0) { // wakeup the corresponding object to handle this message // set the wakeup time of the message next time. // this setted time is stored in the Backup_nextArrivalTime if (UnitripProbe){ boolean responseMess_GetToDestination = RoadTable[M.RouterTableNum].Node(M.NextObjectIndex).EventHandler(M); if (!responseMess_GetToDestination) EQ.insert(M); // The response message does not reach its source else { RoundTripTime = M.getArrivalTime(); LogFile.println("Unitrip Time: "+ RoundTripTime); } } else { RoadTable[M.RouterTableNum].Node(M.NextObjectIndex).EventHandler(M); EQ.insert(M); } flag = true; } if (!flag && (MessageType.compareTo("RoundTripTime-ProbingResponse") == 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 reach its source else { RoundTripTime = M.getArrivalTime(); LogFile.println("Round Trip Time: "+ RoundTripTime); } flag = true; } 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("Probe-start") == 0)) { // probing agent generates a new probing route // generate the next probing message generation message // set the next probing start message time // let the bottleneck link reset the start time to measure bandwidth // probing message number always from 1 to ProbingMessNum // generate a couple of new probing messages: "ICMP-request" double NextSendingTime = M.getArrivalTime(); for (int j=1; j<=MultipleMessNum;j++) { // generate the Cprobing mess NewM = new Message(j,M.RouterTableNum,RoadTable[M.RouterTableNum].numOfNode, NextSendingTime,"ICMP-request",46*8,NextSendingTime,0,UnitripProbe); //if (j==1) RoadTable[NewM.RouterTableNum].Node(NewM.NextObjectIndex).EventHandler(NewM); EQ.insert(NewM); //NextSendingTime = NextSendingTime + TInternalTime; //NextSendingTime = NextSendingTime + (rnd.nextInt(12)*1e-4); NextSendingTime = NewM.getArrivalTime(); } // generate the next "Probing-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("ICMP-request") == 0)) { // wakeup the corresponding object to handle this message // set the wakeup time of the message next time. if (UnitripProbe){ 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 else { //double delaytime = M.getArrivalTime() - M.Pstarting_time - RoundTripTime; double NewRoundTripTime = M.getArrivalTime() - M.Pstarting_time; double Measured_Band ; Measured_Band = (LinkBandwidth * RoundTripTime)/NewRoundTripTime; PFile.println("Starting time: " + M.Pstarting_time); for (int i=0; i 0.0000368) // results is over 10M Measued_Band = (46*8)/delaytime; else Measued_Band = LinkBandwidth; */ PFile.println("Starting time: " + M.Pstarting_time); for (int i=0; i= Start_MeaTime) { // update the log file and 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); } }