tweak, tweak the tutorial

This commit is contained in:
Craig Dowell
2008-06-30 11:42:38 -07:00
parent 8a6ed9603e
commit d714797804
5 changed files with 220 additions and 204 deletions

View File

@@ -136,7 +136,7 @@ object itself.
csmaNodes.Create (nCsma);
@end verbatim
The next line of code @code{Get}s the first node (as in having an index of one)
The next line of code @code{Gets} the first node (as in having an index of one)
from the point-to-point node container and adds it to the container of nodes
that will get CSMA devices. The node in question is going to end up with a
point-to-point device @emph{and} a CSMA device. We then create a number of
@@ -497,7 +497,7 @@ node number code{nCsma + 1}. This can become annoyingly difficult in larger
simulations.
An alternate way, which we use here, is to realize that the
@code{NodeContainer}s contain pointers to @command{ns-3} @code{Node} Objects.
@code{NodeContainers} contain pointers to @command{ns-3} @code{Node} Objects.
The @code{Node} Object has a method called @code{GetId} which will return that
node's ID. Let's go take a look at the Doxygen for the @code{Node} and locate
that method, which is further down in the code than we've seen so far.
@@ -681,7 +681,7 @@ part of the bus (CSMA) network.
csmaNodes.Create (nCsma);
@end verbatim
The next line of code @code{Get}s the first node (as in having an index of one)
The next line of code @code{Gets} the first node (as in having an index of one)
from the point-to-point node container and adds it to the container of nodes
that will get CSMA devices. The node in question is going to end up with a
point-to-point device and a CSMA device. We then create a number of ``extra''

View File

@@ -63,7 +63,7 @@ In @command{ns-3} there is no real concept of operating system and especially
no concept of privilege levels or system calls. We do, however, have the
idea of an application. Just as software applications run on computers to
perform tasks in the ``real world,'' @command{ns-3} applications run on
@command{ns-3} @code{Node}s to drive simulations in the simulated world.
@command{ns-3} @code{Nodes} to drive simulations in the simulated world.
@cindex class Application
In @command{ns-3} the basic abstraction for a user program that generates some
@@ -85,16 +85,17 @@ In the real world, one can connect a computer to a network. Often the media
over which data flows in these netowrks are called @emph{channels}. When
you connect your Ethernet cable to the plug in the wall, you are connecting
your computer to an Ethernet communication channel. In the simulated world
of @command{ns-3} one connects a @code{Node} to an object representing a
of @command{ns-3}, one connects a @code{Node} to an object representing a
communication channel. Here the basic communication subnetwork abstraction
is called the channel and is represented in C++ by the class @code{Channel}.
The @code{Channel} class provides methods for managing communication
subnetwork objects and connecting nodes to them. They may also be specialized
by developers in the object oriented programming sense. A @code{Channel}
specialization may model something as simple as a wire. The specialized
@code{Channel} can also model things as complicated as a large Ethernet
switch, or three-dimensional space in the case of wireless networks.
subnetwork objects and connecting nodes to them. @code{Channels} may also be
specialized by developers in the object oriented programming sense. A
@code{Channel} specialization may model something as simple as a wire. The
specialized @code{Channel} can also model things as complicated as a large
Ethernet switch, or three-dimensional space full of obstructions in the case
of wireless networks.
We will use specialized versions of the @code{Channel} called
@code{CsmaChannel}, @code{PointToPointChannel} and @code{WifiChannel} in this
@@ -108,9 +109,10 @@ access} communication medium. This gives us Ethernet-like functionality.
It used to be the case that if you wanted to connect a computers to a network,
you had to buy a specific kind of network cable and a hardware device called
(in PC terminology) a @emph{peripheral card} that needed to be installed in
your computer. These cards were called Network Interface Cards, or
@emph{NIC}s. Today most computers come with the network controller hardware
built in and users don't see these building blocks.
your computer. If the peripheral card implemented some networking function,
theys were called Network Interface Cards, or @emph{NICs}. Today most
computers come with the network interface hardware built in and users don't
see these building blocks.
A NIC will not work without a software driver to control the hardware. In
Unix (or Linux), a piece of peripheral hardware is classified as a
@@ -122,9 +124,9 @@ to these net devices by names such as @emph{eth0}.
In @command{ns-3} the @emph{net device} abstraction covers both the software
driver and the simulated hardware. A net device is ``installed'' in a
@code{Node} in order to enable the @code{Node} to communicate with other
@code{Node}s in the simulation via @code{Channel}s. Just as in a real
@code{Nodes} in the simulation via @code{Channels}. Just as in a real
computer, a @code{Node} may be connected to more than one @code{Channel} via
multiple @code{NetDevice}s.
multiple @code{NetDevices}.
The net device abstraction is represented in C++ by the class @code{NetDevice}.
The @code{NetDevice} class provides methods for managing connections to
@@ -145,25 +147,26 @@ a @code{WifiChannel}.
In a real network, you will find host computers with added (or built-in)
NICs. In @command{ns-3} we would say that you will find @code{Nodes} with
attached @code{NetDevices}. In a large simulated network you will need to
arrange many connections between @code{Node}s, @code{NetDevice}s and
@code{Channel}s.
arrange many connections between @code{Nodes}, @code{NetDevices} and
@code{Channels}.
Since connecting @code{NetDevice}s to @code{Node}s, @code{NetDevice}s
to @code{Channel}s, assigning IP addresses, etc., are such common tasks
Since connecting @code{NetDevices} to @code{Nodes}, @code{NetDevices}
to @code{Channels}, assigning IP addresses, etc., are such common tasks
in @command{ns-3}, we provide what we call @emph{topology helpers} to make
this as easy as possible. For example, will take several distinct
this as easy as possible. For example, it may take many distinct
@command{ns-3} core operations to create a NetDevice, add a MAC address,
connect the net device to a @code{Node}, configure the protocol stack, and
then connect the @code{NetDevice} to a @code{Channel}. More operations would
be required to connect multiple devices onto multipoint channels and then to
connect networks together into internetworks. We use topology helper objects
to combine those many distinct operations into an easy to use model.
install that net device on a @code{Node}, configure the node's protocol stack,
and then connect the @code{NetDevice} to a @code{Channel}. Even more
operations would be required to connect multiple devices onto multipoint
channels and then to connect individual networks together into internetworks.
We provide topology helper objects that combine those many distinct operations
into an easy to use model for your convenience.
@c ========================================================================
@c A First ns-3 script
@c ========================================================================
@node A First ns-3 Script
@section A First ns-3 script
@section A First ns-3 Script
@cindex first script
If you downloaded the system as was suggested above, you will have a release
of @command{ns-3} in a directory called @code{repos} under your home
@@ -180,7 +183,8 @@ directory structure something like the following:
Change into the examples directory. You should see a file named
@code{first.cc} located there. This is a script that will create a simple
point-to-point link between two nodes and echo a single packet between the
nodes. Let's take a look at that script line by line.
nodes. Let's take a look at that script line by line, so go ahead and open
@code{first.cc} in your favorite editor.
@subsection Boilerplate
The first line in the file is an emacs mode line. This tells emacs about the
@@ -195,17 +199,20 @@ out of the way immediately. The @code{ns-3} project, like most large
projects, has adopted a coding style to which all contributed code must
adhere. If you want to contribute your code to the project, you will
eventually have to conform to the @command{ns-3} coding standard as described
in the file @code{doc/codingstd.txt}. We recommend that you, well, just get
used to the look and feel of @code{ns-3} code and adopt this standard whenever
you are working with our code. All of the development team have done so.
The emacs mode line above makes it easier to get the formatting correct if you
use the emacs editor.
in the file @code{doc/codingstd.txt} or shown on the project web page
@uref{http://www.nsnam.org/codingstyle.html,,here}.
We recommend that you, well, just get used to the look and feel of @code{ns-3}
code and adopt this standard whenever you are working with our code. All of
the development team and contributors have done so with various amounts of
grumbling. The emacs mode line above makes it easier to get the formatting
correct if you use the emacs editor.
The @command{ns-3} simulator is licensed using the GNU General Public
License. You will see the appropriate GNU legalese at the head of every file
in the @command{ns-3} distribution. Often you will see a copyright notice for
one of the institutions involved in the @code{ns-3} project and an author
listed.
one of the institutions involved in the @code{ns-3} project above the GPL
text and an author listed below.
@verbatim
/*
@@ -225,16 +232,7 @@ listed.
@end verbatim
@subsection Module Includes
The code proper starts with a number of include statements. To help our high
level users deal with the large number of include files present in the system,
we group includes according to relatively large modules. We provide a single
include file that, in turn, includes all of the include files used in each
module. Rather than having to look up exactly what header you need, and
possibly have to get dependencies right, we give you the ability to load a
group of files at a large granularity. This is not the most efficient approach
but it certainly makes writing scripts much easier. Each of the
@command{ns-3} files is placed in a directory called @code{ns3} (under the
build directory) to help avoid include file name collisions.
The code proper starts with a number of include statements.
@verbatim
#include "ns3/core-module.h"
@@ -243,20 +241,35 @@ build directory) to help avoid include file name collisions.
#include "ns3/helper-module.h"
@end verbatim
The @code{ns3/core-module.h} file corresponds to the ns-3 module you will find
in the directory @code{src/core} in your downloaded release distribution. If
you list this directory you will find a large number of header files. When
you do a build, Waf will place public header files in an @code{ns3} directory
under the appropriate @code{build/debug} or @code{build/optimized} directory
depending on your configuration. Waf will also automatically generate a module
include file to load all of the public header files. Since you are following
this tutorial religiously, you will already have done a
To help our high-level script users deal with the large number of include
files present in the system, we group includes according to relatively large
modules. We provide a single include file that will recursively load all of
the include files used in each module. Rather than having to look up exactly
what header you need, and possibly have to get a number of dependencies right,
we give you the ability to load a group of files at a large granularity. This
is not the most efficient approach but it certainly makes writing scripts much
easier.
Each of the @command{ns-3} include files is placed in a directory called
@code{ns3} (under the build directory) during the build process to help avoid
include file name collisions. The @code{ns3/core-module.h} file corresponds
to the ns-3 module you will find in the directory @code{src/core} in your
downloaded release distribution. If you list this directory you will find a
large number of header files. When you do a build, Waf will place public
header files in an @code{ns3} directory under the appropriate
@code{build/debug} or @code{build/optimized} directory depending on your
configuration. Waf will also automatically generate a module include file to
load all of the public header files.
Since you are, of course, following this tutorial religiously, you will
already have done a
@verbatim
./waf -d debug configure
@end verbatim
to configure the project to perform debug builds. You will also have done a
in order to configure the project to perform debug builds. You will also have
done a
@verbatim
./waf
@@ -264,8 +277,8 @@ to configure the project to perform debug builds. You will also have done a
to build the project. So now if you look in the directory
@code{build/debug/ns-3} you will find the four module include files shown
above. You can take a look at the contents to find that these files will
include all of the public includes in the respective modules.
above. You can take a look at the contents of these files and find that they
do include all of the public include files in their respective modules.
@subsection Ns3 Namespace
The next line in the @code{first.cc} script is a namespace declaration.
@@ -295,12 +308,9 @@ The next line of the script is the following,
We will use this statement as a convenient place to talk about our Doxygen
documentation system. If you look at the project web site,
@uref{http://www.nsnam.org,,ns-3 project}, you will find a link to ``Other
Documentation'' in the navigation bar. If you select this link, you will be
taken to our documentation page. You will find links to our development
@code{ns-3-dev} documentation as well as that for our latest release. If you
select the @code{HTML} link you will be taken to the Doxygen documentation for
that version.
@uref{http://www.nsnam.org,,ns-3 project}, you will find a link to ``APIs
(Doxygen)'' in the navigation bar. If you select this link, you will be
taken to our documentation page.
Along the left side, you will find a graphical representation of the structure
of the documentation. A good place to start is the @code{NS-3 Modules}
@@ -308,20 +318,24 @@ of the documentation. A good place to start is the @code{NS-3 Modules}
module documentation. The concept of module here ties directly into the
module include files discussed above. It turns out that the @command{ns-3}
logging subsystem is part of the @code{core} module, so go ahead and expand
that documentation node. Now, open the @code{Debugging} book and then select
the @code{Logging} page.
that documentation node. Now, expand the @code{Debugging} book and then
select the @code{Logging} page.
You should now be looking at the Doxygen documentation for the Logging module.
In the list of @code{#define}s you will see @code{NS_LOG_COMPONENT_DEFINE}.
It would probably be good to look for the ``Detailed Description'' of the
logging module now to get a feel for the overall operation and then look at
In the list of @code{#define}s at the top of the page you will see the entry
for @code{NS_LOG_COMPONENT_DEFINE}. Before jumping in, it would probably be
good to look for the ``Detailed Description'' of the logging module to get a
feel for the overall operation. You can either scroll down or select the
``More...'' link under the collaboration diagram to do this.
Once you have a general idea of what is going on, go ahead and take a look at
the specific @code{NS_LOG_COMPONENT_DEFINE} documentation. I won't duplicate
the documentation here, but to summarize, this line declares a logging
component called @code{FirstScriptExample} that allows you to enable and
disable console message logging by reference to the name.
@subsection Main Function
The next lines of the script you will find are:
The next lines of the script you will find are,
@verbatim
int
@@ -329,10 +343,10 @@ The next lines of the script you will find are:
{
@end verbatim
This is just the declaration of the main function of your program. Just as in
any C++ program, you need to define a main function that will be the first
function run. There is nothing at all special here. Your @command{ns-3}
script is just a C++ program.
This is just the declaration of the main function of your program (script).
Just as in any C++ program, you need to define a main function that will be
the first function run. There is nothing at all special here. Your
@command{ns-3} script is just a C++ program.
The next two lines of the script are used to enable two logging components that
are built into the Echo Client and Echo Server applications:
@@ -342,14 +356,14 @@ are built into the Echo Client and Echo Server applications:
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
@end verbatim
If you have read over the Logging component documentation you will see that
there are a number of levels of detail that you can enable on each component.
These two lines of code enable debug logging at the INFO level for echo
clients and servers. This will result in the application printing out
messages as packets are sent and received.
If you have read over the Logging component documentation you will have seen
that there are a number of levels of logging verbosity/detail that you can
enable on each component. These two lines of code enable debug logging at the
INFO level for echo clients and servers. This will result in the application
printing out messages as packets are sent and received during the simulation.
Now we will get directly to the business of creating a topology and running
a simulation. We will use the topology helper objects to make this job as
a simulation. We use the topology helper objects to make this job as
easy as possible.
@subsection Topology Helpers
@@ -379,7 +393,7 @@ applications and peripheral cards. The @code{NodeContainer} topology helper
provides a convenient way to create, manage and access any @code{Node} objects
that we create in order to run a simulation. The first line above just
declares a NodeContainer which we call @code{nodes}. The second line calls the
@code{Create} method on the @code{nodes} object that asks the container to
@code{Create} method on the @code{nodes} object and asks the container to
create two nodes. As described in the Doxygen, the container calls down into
the @command{ns-3} system proper to create two @code{Node} objects and stores
pointers to those objects internally.
@@ -416,8 +430,8 @@ The first line
PointToPointHelper pointToPoint;
@end verbatim
creates a @code{PointToPointHelper} object on the stack. From a high-level
perspective the next line,
instantiates a @code{PointToPointHelper} object on the stack. From a
high-level perspective the next line,
@verbatim
pointToPoint.SetDeviceParameter ("DataRate", StringValue ("5Mbps"));
@@ -436,7 +450,7 @@ attribute. Most user-visible @command{ns-3} objects have similar lists of
attributes. We use this mechanism to easily configure simulations without
recompiling as you will see in a following section.
Similar to the ``DataRate'' on the @code{PointToPointNetDevice} we find a
Similar to the ``DataRate'' on the @code{PointToPointNetDevice} you will find a
``Delay'' attribute associated with the @code{PointToPointChannel}. The
final line,
@@ -446,14 +460,14 @@ final line,
tells the @code{PointToPointHelper} to use the value ``2ms'' (two milliseconds)
as the value of the transmission delay of every point to point channel it
creates.
subsequently creates.
@subsubsection NetDeviceContainer
At this point in the script, we have a @code{NodeContainer} that contains
two nodes. We have a @code{PointToPointHelper} that is primed and ready to
make @code{PointToPointNetDevices} and wire @code{PointToPointChannel} objects
between them. Just as we used the @code{NodeContainer} topology helper object
to create the @code{Node}s for our simulation, we will ask the
to create the @code{Nodes} for our simulation, we will ask the
@code{PointToPointHelper} to do the work involved in creating, configuring and
installing our devices for us. We will need to have a list of all of the
NetDevice objects that are created, so we use a NetDeviceContainer to hold
@@ -518,7 +532,7 @@ and increase monotonically, so the first address allocated from this base will
be 10.1.1.1, followed by 10.1.1.2, etc. The low level @command{ns-3} system
actually remembers all of the IP addresses allocated and will generate a
fatal error if you accidentally cause the same address to be generated twice
(which is a very hard to find error, by the way).
(which is a very hard to debug error, by the way).
The next line of code,
@@ -548,7 +562,7 @@ underlying objects. Here, we use @code{UdpEchoServerHelper} and
@subsubsection UdpEchoServerHelper
The following lines of code in our example script, @code{first.cc}, are used
to set up a UDP echo server application on one of the nodes we have previously
created and connected using a point-to-point link.
created.
@verbatim
UdpEchoServerHelper echoServer;
@@ -578,15 +592,16 @@ work here.
We now see that @code{echoServer.Install} is going to install a
@code{UdpEchoServerApplication} on the node found at index number one of the
@code{NodeContainer} we used to manage our nodes. @code{Install} will return
a container that has all of the applications (one in this case since we passed
a @code{NodeContainer} containing one node) made by the helper.
a container that holds pointers to all of the applications (one in this case
since we passed a @code{NodeContainer} containing one node) created by the
helper.
Applications require a time to ``start'' generating traffic and a time to
``stop.'' These times are set using @code{ApplicationContainer} methods
@code{Start} and @code{Stop}. These methods take @code{Time} parameters.
In this case, we use an explicit conversion sequence to take the C++ double
1.0 and convert it to an @command{ns-3} @code{Time} object using a
@code{Seconds ()} cast. The two lines,
Applications require a time to ``start'' generating traffic and may take an
optional time to ``stop.'' We provide both. These times are set using the
@code{ApplicationContainer} methods @code{Start} and @code{Stop}. These
methods take @code{Time} parameters. In this case, we use an explicit C++
conversion sequence to take the C++ double 1.0 and convert it to an
@command{ns-3} @code{Time} object using a @code{Seconds} cast. The two lines,
@verbatim
serverApps.Start (Seconds (1.0));
@@ -596,14 +611,14 @@ In this case, we use an explicit conversion sequence to take the C++ double
will cause the echo server application to @code{Start} (enable itself) at one
second into the simulation and to @code{Stop} (disable itself) at ten seconds
into the simulation. By virtue of the fact that we have implicilty declared
a simulation event at ten seconds, the simulation will last at least ten
seconds.
a simulation event (the application stop event) to be executed at ten seconds,
the simulation will last at least ten seconds.
@subsubsection UdpEchoClientHelper
The echo client application is set up in a substantially method similar to the
server. There is an underlying @code{UdpEchoClientApplication} that is
managed by an @code{UdpEchoClientHelper}.
The echo client application is set up in a method substantially similar to
that for the server. There is an underlying @code{UdpEchoClientApplication}
that is managed by an @code{UdpEchoClientHelper}.
@verbatim
UdpEchoClientHelper echoClient;
@@ -620,24 +635,25 @@ managed by an @code{UdpEchoClientHelper}.
For the echo client, however, we need to set four different attributes. The
first attribute is set using the @code{SetRemote} method. Recall that
we used an @code{Ipv4InterfaceContainer} to keep track of the IP addresses we
assigned to our devices. As a result of the allocation, the zeroth interface
in the @code{interfaces} container cooresponds to the IP address of the
zeroth node in the @code{nodes} container. The first interface in the
@code{interfaces} container cooresponds to the IP address of the first node in
the @code{nodes} container. So, in the following line of code (reproduced
from above), we are setting the remote address of the client to be the IP
address assigned to the node on which the server resides, and we tell it to
send packets to port nine.
assigned to our devices. The zeroth interface in the @code{interfaces}
container is going to coorespond to the IP address of the zeroth node in the
@code{nodes} container. The first interface in the @code{interfaces}
container cooresponds to the IP address of the first node in the @code{nodes}
container. So, in the following line of code (reproduced from above), we are
setting the remote address of the client to be the IP address assigned to the
node on which the server resides. We also tell it to send packets to port
nine while we are at ti.
@verbatim
echoClient.SetRemote (interfaces.GetAddress (1), 9);
@end verbatim
The ``MaxPackets'' attribute tells the client the maximum number of packets
it can send. The ``Interval'' attribute tells the client how long to wait
between packets, and the ``PacketSize'' attribute tells the client how large
its packets should be. With this combination of attributes, we are telling
the client to send one 1024-byte packet.
we allow it to send during the simulation. The ``Interval'' attribute tells
the client how long to wait between packets, and the ``PacketSize'' attribute
tells the client how large its packet payloads should be. With this
particular combination of attributes, we are telling the client to send one
1024-byte packet.
Just as in the case of the echo server, we tell the echo client to @code{Start}
and @code{Stop}, but here we start the client one second after the server is
@@ -667,13 +683,13 @@ looking through the list of scheduled events and executing them. First it
will run the event at 1.0 seconds, which will enable the echo server
application. Then it will run the event scheduled for t=2.0 seconds which
will start the echo client application. The start event implementation in
the echo client will begin the data transfer phase of the simulation by
sending a packet to the server.
the echo client application will begin the data transfer phase of the
simulation by sending a packet to the server.
The act of sending the packet to the server will trigger a chain of events
which will be automatically scheduled and which will perform the mechanics of
the packet echo according to the various timing parameters that we have set
in the script.
that will be automatically scheduled behind the scene and which will perform
the mechanics of the packet echo according to the various timing parameters
that we have set in the script.
Eventually, since we only send one packet, the chain of events triggered by
that single client echo request will taper off and the simulation will go
@@ -704,31 +720,31 @@ built if you run Waf. Let's try it. Copy @code{examples/first.cc} into
the @code{scratch} directory.
@verbatim
~/repos/ns-3-tutorial > cp examples/first.cc scratch/
~/repos/ns-3-dev > cp examples/first.cc scratch/
@end verbatim
and then build it using waf,
@verbatim
~/repos/ns-3-tutorial > ./waf
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf
Entering directory `/home/craigdo/repos/ns-3-dev/build'
[432/477] cxx: scratch/first.cc -> build/debug/scratch/first_2.o
[475/477] cxx_link: build/debug/scratch/first_2.o ...
Compilation finished successfully
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
You can now run the example (note that if you build your program in the scratch
directory you must run it out of the scratch direcory):
@verbatim
~/repos/ns-3-tutorial > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
Here you see that the build system checks to make sure that the file has been

View File

@@ -33,15 +33,14 @@
@cindex Cygwin
@cindex GNU
@cindex toolchain
From this point forward, we are going to assume that the reader is working in
Linux or a Linux emulation environment (Linux, Cygwin, etc.) and has the GNU
toolchain installed and verified.
@cindex Mercurial
@cindex Waf
We are going to assume that you have Mercurial and Waf installed and running
on the target system as described in the Getting Started section of the
@command{ns-3} web site: @uref{http://www.nsnam.org/getting_started.html}.
From this point forward, we are going to assume that the reader is working in
Linux or a Linux emulation environment (Linux, Cygwin, etc.) and has the GNU
toolchain installed and verified. We are also going to assume that you have
Mercurial and Waf installed and running on the target system as described in
the Getting Started section of the @command{ns-3} web site:
@uref{http://www.nsnam.org/getting_started.html}.
@cindex tarball
The @command{ns-3} code is available in Mercurial repositories on the server
@@ -67,15 +66,15 @@ official release.
Since the release numbers are going to be changing, I will stick with
the more constant ns-3-dev here in the tutorial, but you can replace the
string ns-3-dev with your choice of release (e.g., ns-3.1) in the text below.
You can find the latest version of the code either by inspection of the
repository list or by going to the ``Getting Started'' web page and looking
for the latest release identifier.
string ``ns-3-dev'' with your choice of release (e.g., ns-3.1) in the text
below. You can find the latest version of the code either by inspection of
the repository list or by going to the ``Getting Started'' web page and
looking for the latest release identifier.
One practice is to create a directory called @code{repos} in one's home
directory under which one can keep local Mercurial repositories.
@emph{Hint: we will assume you do this later in the tutorial.} If you adopt
that approach, you can get a copy of any of the development versions of
that approach, you can get a copy of the development version of
@command{ns-3} by typing the following into your Linux shell (assuming you
have installed Mercurial):
@@ -86,7 +85,8 @@ have installed Mercurial):
hg clone http://code.nanam.org/ns-3-dev
@end verbatim
As the hg command executes, you should see something like the following,
As the hg (Mercurial) command executes, you should see something like the
following,
@verbatim
destination directory: ns-3-dev
@@ -169,7 +169,7 @@ The build system is now configured and you can build the debug versions of
the @command{ns-3} programs by simply typing,
@verbatim
./waf check
./waf
@end verbatim
You will see many Waf status messages displayed as the system compiles. The
@@ -217,10 +217,10 @@ test has passed.
This command is typically run by @code{users} to quickly verify that an
@command{ns-3} distribution has built correctly.
You can also run @code{regression tests} to ensure that your distribution and
tool chain have produced binaries that generate trace files which are
compatible with reference trace files stored in a central location. To run the
regression tests you run Waf with the regression flag.
You can also run our regression test suite to ensure that your distribution and
tool chain have produced binaries that generate output that is identical to
reference output files stored in a central location. To run the regression
tests, you provide Waf with the regression flag.
@verbatim
./waf --regression
@@ -231,16 +231,16 @@ built and will then look for trace files in the aforementioned centralized
location. If your tool chain includes Mercurial, the regression tests will
be downloaded from a repository at @code{code.nsnam.org}. If you do not have
Mercurial installed, the reference traces will be downloaded from a tarball
located in the @code{releases} section of @code{www.nsnam.org}. The
particular name of the reference trace location is built from the
@command{ns-3} version located in the VERSION file, so don't change that
string yourself unless you know what you are doing.
located in the releases section of @code{www.nsnam.org}. The particular name
of the reference trace location is built from the @command{ns-3} version
located in the VERSION file, so don't change that string yourself unless you
know what you are doing.
Once the reference traces are downloaded to your local machine, Waf will run
a number of tests that generate trace files. The content of these trace
files are compared with the reference traces just downloaded. If they are
identical, the regression tests report a PASS status. If the regression tests
pass, you should see something like,
a number of tests that generate what we call trace files. The content of
these trace files are compared with the reference traces just downloaded. If
they are identical, the regression tests report a PASS status. If the
regression tests pass, you should see something like,
@verbatim
~/repos/ns-3-dev > ./waf --regression
@@ -264,7 +264,8 @@ pass, you should see something like,
If a regression tests fails you will see a FAIL indication along with a
pointer to the offending trace file and its associated reference trace file
along with a suggestion on how to run diff in order to see what has gone awry.
along with a suggestion on diff parameters and options in order to see what
has gone awry.
@c ========================================================================
@c Running a Script
@@ -276,7 +277,7 @@ along with a suggestion on how to run diff in order to see what has gone awry.
We typically run scripts under the control of Waf. This allows the build
system to ensure that the shared library paths are set correctly and that
the libraries are available at run time. To run a program, simply use the
@code{run} option in Waf. Let's run the @command{ns-3} equivalent of the
@code{--run} option in Waf. Let's run the @command{ns-3} equivalent of the
ubiquitous hello world program by typing the following:
@verbatim
@@ -291,7 +292,8 @@ produces the following output.
Hello Simulator
@end verbatim
@emph{Congratulations. You are now an ns-3 user.}
If you want to run programs under another tool such as gdb or valgrind,
see this @uref{http://www.nsnam.org/wiki/index.php/User_FAQ#How_to_run_NS-3_programs_under_another_tool,,wiki entry}.
@emph{Congratulations. You are now an ns-3 user.}

View File

@@ -126,7 +126,7 @@ broad sequences of events.
* The Web::
* Mercurial::
* Waf::
* Environment Idioms Design Patterns::
* Development Environment::
* Socket Programming::
@end menu
@@ -134,21 +134,19 @@ broad sequences of events.
@section The Web
@cindex www.nsnam.org
@cindex documentation
@cindex architecture
There are several important resources of which any @command{ns-3} user must be
aware. The main web site is located at @uref{http://www.nsnam.org} and
provides access to basic information about the ns-3 system. Detailed
documentation is available through the main web site at
@uref{http://www.nsnam.org/documents.html}.
@uref{http://www.nsnam.org/documents.html}. You can also find documents
relating to the system architecture from this page.
@cindex documentation
@cindex architecture
You can find documents relating to the system architecture from this page,
and also gain access to the detailed software documentation. There is a Wiki
that complements the main ns-3 web site which you will find at
@uref{http://www.nsnam.org/wiki/}.
You will find user and developer FAQs there, as well as troubleshooting
guides, third-party contributed code, papers, etc.
There is a Wiki that complements the main ns-3 web site which you will find at
@uref{http://www.nsnam.org/wiki/}. You will find user and developer FAQs
there, as well as troubleshooting guides, third-party contributed code,
papers, etc.
@cindex mercurial repository
@cindex ns-3-dev repository
@@ -208,8 +206,8 @@ order to extend the system in most cases.
For those interested in the gory details of Waf, the main web site can be
found at @uref{http://freehackers.org/~tnagy/waf.html}.
@node Environment Idioms Design Patterns
@section Environment, Idioms, and Design Patterns
@node Development Environment
@section Development Environment
@cindex C++
As mentioned above, scripting in ns-3 is done in C++. A working
@@ -278,5 +276,5 @@ not have access to a copy of the book, the echo clients and servers shown in
the website above) you will be in good shape to understand the tutorial.
There is a similar book on Multicast Sockets,
@uref{http://www.elsevier.com/wps/product/cws_home/700736,,Multicast Sockets, Makofske and Almeroth}.
that covers material you may need to understand for the multicast examples in
the distribution.
that covers material you may need to understand if you look at the multicast
examples in the distribution.

View File

@@ -93,13 +93,13 @@ in the @code{first.cc} script you have already built. Go ahead and run the
script just as you did previously,
@verbatim
~/repos/ns-3-tutorial > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
The ``Sent'' and ``Received'' messages are actually logging messages from the
@@ -125,7 +125,7 @@ increase the logging level and get more information without changing the
script and recompiling by setting the NS_LOG environment variable like this:
@verbatim
~/repos/ns-3-tutorial > export NS_LOG=UdpEchoClientApplication=level_all
~/repos/ns-3-dev > export NS_LOG=UdpEchoClientApplication=level_all
@end verbatim
This sets the environment variable @code{NS_LOG} to the string,
@@ -141,8 +141,8 @@ you run the script with NS_LOG set this way you should see the following
output:
@verbatim
~/repos/ns-3-tutorial > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:StartApplication()
@@ -155,7 +155,7 @@ output:
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
The only additional debug information provided by the application is from
@@ -194,8 +194,8 @@ that every message from the given log component is prefixed with the component
name.
@verbatim
~/repos/ns-3-tutorial > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:StartApplication()
@@ -208,7 +208,7 @@ name.
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
You can now see all of the messages coming from the UDP echo client application
@@ -231,8 +231,8 @@ echo client and server applications. You may see that this can be very useful
in debugging problems.
@verbatim
~/repos/ns-3-tutorial > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
@@ -251,7 +251,7 @@ in debugging problems.
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
It is also sometimes useful to be able to see the simulation time at which a
@@ -265,8 +265,8 @@ log message is generated. You can do this by ORing in the prefix_time bit.
If you run the script now, you should see the following output:
@verbatim
~/repos/ns-3-tutorial > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
0ns UdpEchoServerApplication:UdpEchoServer()
0ns UdpEchoClientApplication:UdpEchoClient()
@@ -287,7 +287,7 @@ If you run the script now, you should see the following output:
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
You can see that the constructor for the UdpEchoServer was called at a
@@ -324,7 +324,7 @@ for the single packet echo) but you can redirect this information into a file
and look through it with your favorite editor if you like,
@verbatim
~/repos/ns-3-tutorial > ./waf --run scratch/first >& log.out
~/repos/ns-3-dev > ./waf --run scratch/first >& log.out
@end verbatim
I personally use this quite a bit when I am presented with a problem and I
@@ -365,7 +365,7 @@ Now build the script using waf and clear the @code{NS_LOG} variable to turn
off the torrent of logging we previously enabled:
@verbatim
~/repos/ns-3-tutorial > export NS_LOG=
~/repos/ns-3-dev > export NS_LOG=
@end verbatim
Now, if you run the script, you will not see your new message since its
@@ -376,21 +376,21 @@ to @code{NS_LOG_INFO}. If you just want to see this particular level of
logging, you can enable it by,
@verbatim
~/repos/ns-3-tutorial > export NS_LOG=FirstScriptExample=info
~/repos/ns-3-dev > export NS_LOG=FirstScriptExample=info
@end verbatim
If you now run the script you will see your new ``Creating Topology'' log
message,
@verbatim
~/repos/ns-3-tutorial > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
Creating Topology
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
@c ========================================================================
@@ -430,7 +430,7 @@ and add that two lines of code to the @code{first.cc} script at the start of
for help in the following way,
@verbatim
~/repos/ns-3-tutorial > ./waf --run "scratch/first --PrintHelp"
~/repos/ns-3-dev > ./waf --run "scratch/first --PrintHelp"
@end verbatim
This will ask Waf to run the @code{scratch/first} script and pass the command
@@ -439,8 +439,8 @@ sort out which program gets which argument. The command line parser will
now see the @code{--PrintHelp} argument and respond with,
@verbatim
~/repos/ns-3-tutorial > ./waf --run ``scratch/first --PrintHelp''
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run ``scratch/first --PrintHelp''
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
@@ -448,7 +448,7 @@ now see the @code{--PrintHelp} argument and respond with,
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
Let's focus on the @code{--PrintAttributes} option. We have already hinted
@@ -515,8 +515,8 @@ time prefix.
If you run the script, you should now see the following output,
@verbatim
~/repos/ns-3-tutorial > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run scratch/first
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
0ns UdpEchoServerApplication:UdpEchoServer()
1000000000ns UdpEchoServerApplication:StartApplication()
@@ -527,7 +527,7 @@ If you run the script, you should now see the following output,
10000000000ns UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
Recall that the last time we looked at the simulation time at which the packet
@@ -644,8 +644,8 @@ Now if you run the script and provide the @code{--PrintHelp} argument, you
should see your new @code{User Argument} listed in the help.
@verbatim
~/repos/ns-3-tutorial > ./waf --run "scratch/first --PrintHelp"
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run "scratch/first --PrintHelp"
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
@@ -655,15 +655,15 @@ should see your new @code{User Argument} listed in the help.
--PrintGlobals: Print the list of globals.
User Arguments:
--nPackets: Number of packets to echo
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
If you want to specify the number of packets to echo, you can now do so by
setting the @code{--nPackets} argument in the command line,
@verbatim
~/repos/ns-3-tutorial > ./waf --run "scratch/first --nPackets=2"
Entering directory `/home/craigdo/repos/ns-3-tutorial/build'
~/repos/ns-3-dev > ./waf --run "scratch/first --nPackets=2"
Entering directory `/home/craigdo/repos/ns-3-dev/build'
Compilation finished successfully
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
@@ -671,7 +671,7 @@ setting the @code{--nPackets} argument in the command line,
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
You have now echoed two packets.
@@ -961,15 +961,15 @@ The easiest thing to do at this point will be to use @code{tcpdump} to look
at the @code{pcap} files. Output from dumping both files is shown below:
@verbatim
~/repos/ns-3-tutorial > /usr/sbin/tcpdump -r first-0-0.pcap -nn -tt
~/repos/ns-3-dev > /usr/sbin/tcpdump -r first-0-0.pcap -nn -tt
reading from file first-0-0.pcap, link-type PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024
~/repos/ns-3-tutorial > /usr/sbin/tcpdump -r first-1-0.pcap -nn -tt
~/repos/ns-3-dev > /usr/sbin/tcpdump -r first-1-0.pcap -nn -tt
reading from file first-1-0.pcap, link-type PPP (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024
~/repos/ns-3-tutorial >
~/repos/ns-3-dev >
@end verbatim
You can see in the dump of ``first-0.0.pcap'' (the client device) that the