Written by Tom Laramee for use in the senior level ECE course in Computer Networks 597A, and for use in the graduate-level course ECE671.
Presented is a sample protocol simulation skeleton.
[ Tutorial Index | Lecture Notes | Skeleton Simulation Code | Media Access Simulation Code | Data Link Layer Simulation Code ]Perhaps the most difficult way to write a program is to take someone else's code and modify it to do what you want it to do. It is oftentimes easier to rewrite the program from the beginning (and some of you may choose to do this now) so you have a clear understanding of what each function does.
However, this should not be necessary in the case of network simulations. Remember, the point here is to take the emphasis off of the programming to focus on the understanding of the differnt types of events and how they change the state of the system. Following is an overview of what you need to do to take a network simulation skeleton and modify it to simulate a protocol.
The simulation code is written in C - it should be portable to most any platform with a C compiler (Instructions on porting to an O/S such as Windows are beyond the scope of this tutorial).
However, it is designed to run in conjunction with a UNIX
script on a UNIX operating system (X-Windows interface).
(This provides for a nice interface.)
(An easy port would be to Linux.)
The operating environment is a Posix compliant operating system with an X-Windows interface, such as ULTRIX, IRIX, or Linux.
The compiler is GCC, the "make" utility is used to link multiple binaries together.
The examples are compiled on the DEC ULTRIX machines @ UMass.
To successfully complete this task:
NOTE: If you are not familiar with many of these things, it is not as big a problem as it may seem. Expect to learn a lot. Many of these utilities are very powerful - and you don;t need to become a systems expert on them - you just need to have a very basic understanding of how to use them to get what you want. Example are provided for how to use most of the utilities.
There are 3 zip files:
Download the 3rd file, gunzip it, and untar it.
NOTE: The contents of this tape archive should reside in their own directory. If it is untarred in the same directory as either the skeleton or the other example, there will be a file collision and some files will be overwritten and lost.
The filelist should be as is listed below:
These are the 7 base files in the skeleton package. Listed below is these same filenames with a brief overview of how each one fits into the skeleton simulation module.
NOTE: For a reference on the UNIX makefile, at your UNIX prompt type
...and then
For a reference on the utility gnuplot, at your UNIX prompt type:
At a high level:
This is a header file containing external global variable declarations which are used in the functions which are defined in event.c, global data structures, and prototypes for event functions.
These variables, structures, and functions are grouped together as such because they are generic across all event driven simulations for data link layer and media access protocols. (all the protocols you will simulate in this course).
There should be no reason to modify the code in this file (and in event.c). If you are modifying it - chances are either:
At a lower level:
This file contains:
A collection of functions which are generic across all of the protocols you will be simulating this semester.
Functions include:
This file is a header file containing user-defined MACROS and prototypes for user-defined functions.
More specifically, user defined events, such as:
#define ARRIVAL 0This file contains all of the code which will be modified by the user. There are several functions already defined (some partially coded to demonstrate their intended function):
/* FUNCTIONS WHICH ARE PARTIALLY CODED FOR YOU */ /* ---------------------------- Initialization functions */ short initParams(int argc, char * argv[]); void initAll(void); /* ---------------------------- Display information */ void showParams(FILE * fp); void showCurrentEvent(FILE * fp); void showEventList(FILE * fp); void showReport(FILE * fp); void printStatus(void); */ /* USER DEFINED FUNCTIONS */ /* ---------------------------- Generate event functions */ void genEvent1( int node ); void genEvent2( int node ); void genEvent3( int node ); /* ---------------------------- Process EVENTS */ void processEvent1( void ); void processEvent2( void ); void processEvent3( void );
This is the program which requires the most modification to to test a specific protocol.
At the highest level, the program is set up like so: (the is the pseudo code version - it just shows, in a mixture of code and english, how the program is set up)
main.c:
#includes #defines /* Global variables */ /* function */ initParams() /* 1 = will require modification */ initAll() /* 1 */ showParams() /* 1 */ showEventList() /* 2 = will require NO modification */ showCurrentEvent() /* 2 */ showReport() /* 1 */ printStatus() /* 1 */ gen_arrival() /* 2 */ genEvent1(); /* 3 = will require complete writing */ genEvent2(); /* 3 */ genEvent3(); /* 3 */ processEvent1(); /* 3 */ processEvent2(); /* 3 */ processEvent3(); /* 3 */ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ main() { initParams(); initAll(); showParams(); < loop for X events > { < switch the event type > { case EVENT1: processEvent1(); break; case EVENT2: processEvent2(); break; case EVENT3: processEvent3(); break; } < if we're debugging, print out status information > < see if we're done with the simulation > } printReport() } /* ^^^^^^^^^^^^^^^^^^ end of main ^^^^^^^^^^^^^^^^^^ */
See "Hints on Modifying the Skeleton To Test A Protocol" for ideas on modifying this program.
This is a static file which links the multiple files together during compilation to produce 1 executable program, which is called "sim" in the skeleton.
There is no need to modify this file unless you add more programs to the simulation. It should be quite clear (by looking at the existing makefile) how to modify it to include a new file for compilation.
This is a UNIX shell script which may be modified (enhanced) for more functionality. There are 2 sample scripts provided with the 2 sample protocols which include extensive modifications (if you're looking for ideas).
The script provided is a minimal implementation script which does the following things:
This is a UNIX shell script which produces a driver file to run GNUplot to produce a plot of data.
A "driver file" contains the instructions for GNUplot on:
This file should require modification.
To compile the program, type:
This will compile the separate programs and generate a single executable program called "sim".
To run the simulation (without the script), type:
You will see the following:
No parameters specified on command line... Using the default parameters... Initial simulation parameters... Number of Nodes............: 1 Channel capacity...........: 2.000e+06 System packet arrival rate.: 1.000000 Nodal packet arrival rate..: 1.000000 Simulation results... Number of Nodes.................: 1 Channel capacity................: 2.000e+06 Throughput......................: 1.000
The simulation doesn't actually run here - no events are processed. What you see is the report on the initial simulation parameters, and then the final simulation report, with nothing actually happening in between.
This is because there are no "events" which have been added to this simulation to process - thus, the "skeleton" concept.
The idea here is that you will add the events which are specific to your protocol, and this code will help you simulation them.
To run the program with the script, type:
You will see the following:
sim: Command line parameters are as follows sim: sim: Description.....command line flag: value sim: --------------------------------------------- sim: Number of nodes............(-n): 1 sim: Channel capacity...........(-c): 2.048e6 (bps) sim: System arrival rate........(-S): 1 (frames per sec) sim: sim: Removing old output files... sim: Creating permanent data files... sim: Creating GNUplot files to generate the plots... sim: Compiling... gcc -o sim main.o event.o -lm sim: sim: Successful compilation... sim: Running for several different channel arrival rates sim: The number of cycles to cycle for is: 19 sim: Starting channel arrival rate: 1 sim: Ending channel arrival rate: 1000 sim: In steps of: 50 sim: sim: Hitto continue...
This shows that the simulation is ready to be run 19 times, for system arrival rates ranging from 1 to 1000 and in increments of 50. The program has been compiled from within the script.
Hit return, and the simulation will run 19 times. As it runs, notice that the system arrival rate is increasing in increments of 50. These parameters can be reset to simulate for any system arrival rate range and using any integer increment value.
Each time the simulation runs, it is producing a 1 line data file called: "a".
This data file has 2 numbers in it:
The file will look something like this:
10.000 | 1.000 |
Each time the program runs, the script concatenates this
file to a master data file called: data.utilization
( cat a >> data.utilization)
So, after the program is run 5 times, the data.utilization file looks like this:
1.000 | 1.000 |
51.00 | 1.000 |
101.0 | 1.000 |
151.0 | 1.000 |
201.0 | 1.000 |
This is the data which will be plotted using GNUplot.
The script, sim.sh, calls the other script: sim.gnuplot.sh before it runs the simulation. This script produces a GNUplot driver file which will be used to plot the data in:
data.utilization
The driver file, called: data.plot1, looks like this:
set terminal postscript landscape "helvetica" 20 set output "data.plot1.ps" set format xy "%g" set xlabel "System Arrival Rate" set ylabel "Channel Utilization" set title "Utilization vs. System Arrival Rate" set key plot "data.utilization" t '(1 nodes) Util.' with lines 1
As you can see, this file:
So, when the simulation is done (sim.sh is done running the program 19 times), you will see the following:
sim: sim: Generating plots using gnuplot... sim: First Warning: empty y range [1:1], adjusting to [0.9:1.1] (ignore this error - it will disappear when you write your own simulations) sim: Removing data files... sim: Removing GNUplot driver files... sim: sim: The plot names are as follows: sim: data.plot1.ps sim: sim: Would you like to ghostview the plots now? (y/n)
If you enter "y", you will see the plot which was generated. This is done using a very popular utility for X-Windows called Ghostview. It is a Postscript previewer.
These should be all set. All necessary files are included.
You may want to have a look at the defines which are already there for you, and you may want to add some more to make life easier.
Simply put, there aren't enough here. Typcial variables include:
You need to add the variables which are specific to your protocol.
This function reads in command line parameters and assigns the
values to the appropriate global variables. Right now, there
are only 2 variables on the command line (inside of sim.sh).
The program call looks like this:
where:
It is frequently advantageous to pass several arguments on the command line so you don't need to recompile the program each time you run it. Use this function to do that processing (assignment).
This function assigns/calculates the rest of the global variable values which may be functions of command line parameters.
For example, nodal arrival rate is a function of system arrival rate, and system arrival rate is a command line parameter. So, after system arrival rate is assigned a value in initParams(), nodal arrival rate can be calculated here.
NOTE: Sandy Hill will tell you it's a good idea to initialize ALL of your variables. :-)
This is a function which prints a report of the values of the global variables for your simulation before it starts running.
Add your new variables here.
Change the #define SHOWPARAMS from "stdout" to "NULL" if you don't want to see this report.
This function prints out the current event list. It requires no modification.
This function may require modification if you add events and want to view their specific attributes in the debugging report. Hint: Look at the event data structures, and this function before modifying it.
This function serves 2 purposes:
Right now, the data file printed out is: "system arrival rate" vs. "channel utilization"
More can be added.
This function also has local variables which are used to calculate statistics. One example of this is "utilization". More can be added, and then printed.
This is a debugging function which you may want to add to extensively. I use it at the end of the processing of each event to show me what is happening during the simulation.
Then, when I stop the simulation, I can look at a fairly verbose trace file to show me what is going on during my simulation.
This is a function which generates Poisson arrivals to your system based on "lambdaS" (the system arrival rate). Assuming your simulations is assuming Poisson arrivals (you are), this function should require no modification.
These functions are empty. They are for you to write and are specific to your protocol. Typical examples of events which need to be generated for a simulation are:
For each protocol, there are a finite number of possible events. These must be understood and coded in these functions so they simulate the affect the event has on the system.
For example,
As you write these event functions, you may want to update the #defines in the "main.h" header so they are more intuitive. They are quite generic right now.
For more example, see the 2 sample protocol provided with this tutorial.
These functions are also empty. They are also specific to your protocol. Typically, for each genEvent? function is a corresponding processEvent? function. This should make intuitive sense:
If you generate a "re_arrival" event, then you need to process this event when it occurs. Therefore, you'll have @ least 2 functions:
These functions also must attempt to simulate the behavior of the real system.
For example, a process_collision() event for CSMA might look something like:
void process_collision() { < if any nodes are transmitting, stop (back-off) > < generate a random time to re-arrive to the channel > < schedule a re-arrival event for each node based on their back-off time > < schedule an "end of collision" event - end of channel jamming > }
For more examples, see the 2 simulations provided with this tutorial.
This script has the potential to be heavily modified. If you aren't too familiar with the UNIX operating system, you may want to keep modifications to a minimum.