仿真:分组交换网络的发送延时和传播延时(Java)
程序员文章站
2022-07-10 18:12:23
...
Simulation of Transmission and Propagation Delay in Packet-switched Networks
这是"Computer Networking"中的一个仿真applet,我只是修改了其中关于线程suspend的部分。
看完代码的总体感觉是,仿真的思维方式就是,让用户能非常直观的看到过程和结果。为此付出的代价,真是巨大!
Basics:
transmission delay = packet length / transmission rate
propagation delay = distance / propagation speed
Result:
Source Code:
///////////////////////////////////////
//LineSimApllet
//written by David Grangier, Institut Eurecom, France
//[email protected]
///////////////////////////////////////
package linesim;
//imports
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.applet.*;
import java.util.*;
//Applet Class
public class LineSimApplet extends Applet {
//buttons
Button start=new Button ("Start");
Button stop=new Button ("Reset");
//features lists
MyChoice length=new MyChoice(new String[] {"10 km","100 km","1000 km"},new double[] {10E3,100E3,1E6},3);
MyChoice rate=new MyChoice(new String[] {"512 kps","1 Mbps","10 Mbps","100 Mbps"},new double[] {512E3,1E6,10E6,100E6},2);
MyChoice size=new MyChoice(new String[] {"100 Bytes","500 Bytes","1 kBytes"},new double[] {8E2,4E3,8E3},1);
//to simulate time
Thread timerThread;
TickTask timerTask;
boolean simulationRunning=false;
boolean simulationSuspend=false;
//communication line
Line myLine;
public void init() {
try {
setBackground(Color.white);
add(new Label ("Length",Label.RIGHT));
add(length);
add(new Label("Rate",Label.RIGHT));
add(rate);
add(new Label("Packet size",Label.RIGHT));
add(size);
//start
start.addActionListener(
new ActionListener()
{
public void actionPerformed (ActionEvent event)
{
launchSim();
}
});
add(start);
//stop
Button stop=new Button ("Reset");
stop.addActionListener(
new ActionListener()
{
public void actionPerformed (ActionEvent event)
{
stopSim();
//clear line
myLine.sendTime(0);
//redraw cleared line
LineSimApplet.this.repaint();
}
});
add(stop);
//line
myLine= new Line(40,50,450,10);
}
catch(Exception e) {
e.printStackTrace();
}
}
public void paint (Graphics g)
{
update(g); // eliminate flashing : update is overriden
}
public void update (Graphics g)
{ //work on a offscreen image
Dimension offDimension = getSize();
Image offImage = createImage(offDimension.width, offDimension.height);
Graphics offGraphics = offImage.getGraphics();
myLine.drawLine(offGraphics);
//sender
offGraphics.setColor(Color.blue);
offGraphics.fillRect(10,40,30,30);
offGraphics.setColor(Color.black);
offGraphics.drawString("Sender",5,90);
offGraphics.drawRect(10,40,30,30);
//receiver
offGraphics.setColor(Color.blue);
offGraphics.fillRect(490,40,30,30);
offGraphics.setColor(Color.black);
offGraphics.drawString("Receiver",485,90);
offGraphics.drawRect(490,40,30,30);
offGraphics.drawString("Propagation speed : 2.8 x 10^8 m/sec",175,105);
//display offscreen image
g.drawImage(offImage, 0, 0, this);
}
private void launchSim()
{
setupEnabled(false);
//setup line
myLine.setup(length.getVal(), rate.getVal() );
myLine.emitPacket(size.getVal(),0);
//setup timer
timerTask=new TickTask(1E-5,myLine.totalTime());
timerThread=new Thread(timerTask);
//start simulation
simulationRunning=true;
simulationSuspend=false;
timerThread.start();
}
private void stopSim()
{
timerTask.endNow();
simulationRunning=false;
setupEnabled(true);
}
public void setupEnabled(boolean value)
{
start.setEnabled(value);
length.setEnabled(value);
rate.setEnabled(value);
size.setEnabled(value);
}
//my choice
class MyChoice extends Choice
{
private double vals[];
public MyChoice(String items[], double values[],int defaultValue)
{
for (int i=0; i<items.length;i++) {super.addItem(items[i]);}
vals=values;
select(defaultValue-1);
}
public double getVal() {return vals[super.getSelectedIndex()];}
}
//tickTask
class TickTask implements Runnable
{
private double counter;
private double length;
private double tick;
public TickTask(double t,double l)
{
length=l;
tick=t;
counter=0;
}
public void run()
{
while (LineSimApplet.this.simulationRunning)
{
if (!LineSimApplet.this.simulationSuspend)
{
counter+=tick;
LineSimApplet.this.myLine.sendTime(counter);
LineSimApplet.this.repaint();
if (counter>=length)
{
LineSimApplet.this.myLine.clearPackets();
LineSimApplet.this.simulationSuspend=true;
}
try {LineSimApplet.this.timerThread.sleep(50);} catch (Exception e) { }
}
else // suspend state
{
try {Thread.sleep(500);} catch(Exception e) {}
}
}
}
public void endNow() {
length=counter;
}
}
}
//Line class
class Line
{
//graphic variables
private int gX;
private int gY;
private int gWidth;
private int gHeight;
//characteristic variables
final double celerity = 2.8E+8;
private double length;
private double rate;
//simulation variables
private double time;
private Packet myPacket;
public Line(int x, int y, int w, int h)
{
//graphic init
gX=x;
gY=y;
gWidth=w;
gHeight=h;
}
public void setup(double l, double r)
{
length=l;
rate=r;
}
void sendTime(double now)
{
time=now; //update time
removeReceivedPackets(now);
}
void emitPacket(double s, double eT)
{
myPacket= new Packet(s,eT);
}
private void removeReceivedPackets(double now)
{
if (!(myPacket==null))
{
if ( now>myPacket.emissionTime+(myPacket.size/rate)+length*celerity )
{
clearPackets();
}
}
}
public void clearPackets()
{
myPacket=null;
}
public double totalTime()
{
double emmissionTime=(myPacket.size/rate);
double onLineTime=(length/celerity);
return (emmissionTime+onLineTime);
}
public void drawLine(Graphics g)
{
g.setColor(Color.white);
g.fillRect(gX,gY+1,gWidth,gHeight-2);
g.setColor(Color.black);
g.drawRect(gX,gY,gWidth,gHeight);
g.setColor(Color.red);
g.drawString(timeToString(time),gX+gWidth/2-10,gY+gHeight+15);
drawPackets(g);
}
private void drawPackets(Graphics g)
{
if (!(myPacket==null))
{
double xfirst;
double xlast;
//compute time units
xfirst=time-myPacket.emissionTime;
xlast=xfirst-(myPacket.size/rate);
//compute position
xfirst=xfirst*celerity*gWidth/length;
xlast=xlast*celerity*gWidth/length;
if (xlast<0) {xlast=0;}
if (xfirst>gWidth ) {xfirst=gWidth;}
//draw
g.setColor(Color.red);
g.fillRect(gX+(int)(xlast),gY+1,(int)(xfirst-xlast),gHeight-2);
}
}
static private String timeToString(double now)
{
String res=Double.toString(now*1000);
int dot=res.indexOf('.');
String deci=res.substring(dot+1)+"000";
deci=deci.substring(0,3);
String inte=res.substring(0,dot);
return inte+"."+deci+" ms";
}
}
class Packet
{
double size;
double emissionTime;
Packet(double s, double eT)
{
size=s;
emissionTime=eT;
}
}
转载于:https://my.oschina.net/u/158589/blog/61757
上一篇: 基础储备----HTTP协议
下一篇: 面向对象的方式进行数据交换网络之间的差异