mirror of
https://github.com/bronson-g/simEthernet.git
synced 2025-12-23 21:48:14 -05:00
141 lines
5.8 KiB
Java
141 lines
5.8 KiB
Java
import java.util.*;
|
|
import java.text.*;
|
|
|
|
public class Ethernet {
|
|
private static ArrayList<Device> available(ArrayList<Device> all) {
|
|
ArrayList<Device> available = new ArrayList<Device>();
|
|
for(Device d : all) {
|
|
if(!d.hasPending()) {
|
|
available.add(d);
|
|
}
|
|
}
|
|
return available;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
long seed = 0;
|
|
int numberOfDevices = 0;
|
|
int numberOfFrames = 0;
|
|
int droppedFrames = 0;
|
|
double arrivalRate = 0.0;
|
|
double arrivalTime = 0.0;
|
|
double bytesSent = 0.0;
|
|
double throughput = 0.0;
|
|
double prevTime = 0.0;
|
|
double size = 0.0;
|
|
DecimalFormat df = new DecimalFormat("#.#");
|
|
EventList events = new EventList();
|
|
FrameList frames = new FrameList();
|
|
Random rng;
|
|
ArrayList<Device> devices = new ArrayList<Device>();
|
|
|
|
try {
|
|
seed = Integer.parseInt(args[0]);
|
|
numberOfDevices = Integer.parseInt(args[1]);
|
|
numberOfFrames = Integer.parseInt(args[2]);
|
|
arrivalRate = Double.parseDouble(args[3]);
|
|
arrivalTime = 2560/arrivalRate;
|
|
} catch(NumberFormatException e) {
|
|
System.out.println("Arguments should be positive real numbers.");
|
|
System.exit(-1);
|
|
} catch(ArrayIndexOutOfBoundsException e) {
|
|
System.out.println("Please provide 4 arguments.");
|
|
System.exit(-1);
|
|
} catch(ArithmeticException e) {
|
|
System.out.println("arrival_rate should not be 0.");
|
|
System.exit(-1);
|
|
}
|
|
|
|
System.out.println("Input:\tSeed from user = "+seed);
|
|
|
|
if(seed == 0) {
|
|
seed = System.currentTimeMillis();
|
|
}
|
|
rng = new Random(seed);
|
|
|
|
System.out.println("\tSeed to use = "+seed);
|
|
System.out.println("\t# devices = "+numberOfDevices);
|
|
System.out.println("\t# frames to simulate = "+numberOfFrames);
|
|
System.out.println("\tMean # arrival frames/100 slot times = "+df.format(arrivalRate));
|
|
System.out.println("\tMean arrival time = "+df.format(arrivalTime));
|
|
|
|
for(int i = 0; i < numberOfDevices; i++) {
|
|
devices.add(new Device(i));
|
|
}
|
|
|
|
double arrive = 0.0;
|
|
for(int i = 0; i < numberOfFrames; i++) {
|
|
arrive += rng.nextDouble()*2*arrivalRate;
|
|
size = ((Math.log(1-rng.nextDouble())/(-0.5))*1454)+72;
|
|
EthernetFrame frame = new EthernetFrame(arrive, size, i+1);
|
|
frames.add(frame);
|
|
events.add(new Event(arrive, frame, EventType.ARRIVE));
|
|
}
|
|
|
|
while(!events.complete()) {
|
|
Event next = events.next();
|
|
Event todo;
|
|
ArrayList<Device> availDevices = available(devices);
|
|
Device dev = devices.get(next.getFrame().owner());
|
|
|
|
if(next.typeOfEvent() == EventType.ARRIVE) {
|
|
int index = rng.nextInt(availDevices.size());
|
|
dev = availDevices.get(index);
|
|
|
|
if(availDevices.size() == 0) {
|
|
System.out.println("Devices already have pending frames. Can't assign this frame to a device.");
|
|
System.exit(-1);
|
|
}
|
|
do {
|
|
dev = devices.get(rng.nextInt(numberOfDevices));
|
|
} while(dev.hasPending());
|
|
} else if(next.typeOfEvent() == EventType.SENT) {
|
|
bytesSent+=next.getFrame().size();
|
|
}
|
|
|
|
dev.addFrame(next.getFrame());
|
|
todo = next.execute(dev);
|
|
|
|
if(todo.typeOfEvent() == EventType.COLLISION) {
|
|
events.collision(dev.frameUse());
|
|
System.out.println("Frame "+dev.frameUse().getId()+" sender detects "+dev.frameUse().getCollisions()+"th collision at "+df.format(next.time())+" mus");
|
|
if(dev.frameUse().getCollisions() <= 10) {
|
|
double backoff = rng.nextDouble()*51.2*Math.pow(2.0, dev.frameUse().getCollisions()*1.0);
|
|
events.add(new Event(next.time()+backoff, dev.frameUse(), EventType.LISTEN));
|
|
System.out.println("\t\tbacks off for "+df.format(backoff)+" mus");
|
|
} else {
|
|
droppedFrames++;
|
|
System.out.println("Frame "+dev.frameUse().getId()+" dropped at "+df.format(next.time())+" mus");
|
|
}
|
|
events.collision(next.getFrame());
|
|
System.out.println("Frame "+next.getFrame().getId()+" sender detects "+next.getFrame().getCollisions()+"th collision at "+df.format(next.time())+" mus");
|
|
if(next.getFrame().getCollisions() <= 10) {
|
|
double backoff = rng.nextDouble()*51.2*Math.pow(2.0, next.getFrame().getCollisions()*1.0);
|
|
events.add(new Event(next.time()+backoff, next.getFrame(), EventType.LISTEN));
|
|
System.out.println("\t\tbacks off for "+df.format(backoff)+" mus");
|
|
} else {
|
|
droppedFrames++;
|
|
System.out.println("Frame "+next.getFrame().getId()+" dropped at "+df.format(next.time())+" mus");
|
|
}
|
|
} else if(todo.typeOfEvent() == EventType.FIRST72) {
|
|
if(next.time() > prevTime) {
|
|
dev.cableUse();
|
|
}
|
|
}
|
|
if(todo.typeOfEvent() != EventType.NONE && todo.typeOfEvent() != EventType.COLLISION) {
|
|
events.add(todo);
|
|
} else {
|
|
dev.sent();
|
|
}
|
|
prevTime = next.time();
|
|
}
|
|
|
|
throughput = bytesSent/(prevTime*1000000);
|
|
|
|
System.out.println("Performance Report:");
|
|
System.out.println("\t# simulated frames = "+numberOfFrames+" frames");
|
|
System.out.println("\t# bytes successfully sent = "+df.format(bytesSent)+" bytes");
|
|
System.out.println("\t# dropped frames = "+droppedFrames+" frames");
|
|
System.out.println("\t# Ethernet throughput = "+throughput+" bps = "+df.format(throughput*1000000)+" Mbps");
|
|
}
|
|
} |