merge with HEAD

This commit is contained in:
Mathieu Lacage
2009-07-02 15:35:52 +02:00
6 changed files with 412 additions and 293 deletions

View File

@@ -85,6 +85,23 @@ was just a pass-through to GetDevice ()->GetMtu ().
</p>
</li>
<li><b>GlobalRouteManager::PopulateRoutingTables () and RecomputeRoutingTables () are deprecated </b>
<p>This API has been moved to the helper API and the above functions will
be removed in ns-3.6. The new API is:
<pre>
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
Ipv4GlobalRoutingHelper::RecomputeRoutingTables ();
</pre>
Additionally, these low-level functions in GlobalRouteManager are now public,
allowing more API flexibility at the low level ns-3 API:
<pre>
GlobalRouteManager::DeleteGlobalRoutes ();
GlobalRouteManager::BuildGlobalRoutingDatabase ();
GlobalRouteManager::InitializeRoutes ();
</pre>
</p>
</li>
<li><b>CalcChecksum attribute changes</b>
<p>Four IPv4 CalcChecksum attributes (which enable the computation of
checksums that are disabled by default) have been collapsed into one global

View File

@@ -61,7 +61,6 @@ The actual code begins by loading module include files just as was done in the
#include "ns3/simulator-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
#include "ns3/global-routing-module.h"
@end verbatim
One thing that can be surprisingly useful is a small bit of ASCII art that
@@ -294,10 +293,11 @@ leftmost point-to-point node seen in the topology illustration.
@end verbatim
Since we have actually built an internetwork here, we need some form of
internetwork routing. @command{ns-3} provides what we call a global route
manager to set up the routing tables on nodes. This route manager has a
global function that runs through the nodes created for the simulation and does
the hard work of setting up routing for you.
internetwork routing. @command{ns-3} provides what we call global routing to
help you out. Global routing takes advantage of the fact that the entire
internetwork is accessible in the simulation and runs through the all of the
nodes created for the simulation --- it does the hard work of setting up routing
for you without having to configure routers.
Basically, what happens is that each node behaves as if it were an OSPF router
that communicates instantly and magically with all other routers behind the
@@ -307,7 +307,7 @@ construct the routing tables for each node. Setting up this form of routing
is a one-liner:
@verbatim
GlobalRouteManager::PopulateRoutingTables ();
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
@end verbatim
Next we enable pcap tracing. The first line of code to enable pcap tracing
@@ -329,8 +329,8 @@ that are emitted or consumed by that net device. Another way is to pick
one of the devices and place it in promiscuous mode. That single device
then ``sniffs'' the network for all packets and stores them in a single
pcap file. This is how @code{tcpdump}, for example, works. That final
parameter tells the CSMA helper whether or not to capture packets in
promiscuous mode.
parameter tells the CSMA helper whether or not to arrange to capture
packets in promiscuous mode.
In this example, we are going to select one of the devices on the CSMA
network and ask it to perform a promiscuous sniff of the network, thereby
@@ -350,10 +350,10 @@ the @code{first.cc} example.
}
@end verbatim
In order to run this example, you have to copy the @code{second.cc} example
script into the scratch directory and use waf to build just as you did with
In order to run this example, copy the @code{second.cc} example script into
the scratch directory and use waf to build just as you did with
the @code{first.cc} example. If you are in the top-level directory of the
repository you would type,
repository you just type,
@verbatim
cp examples/second.cc scratch/mysecond.cc
@@ -380,18 +380,19 @@ Since we have set up the UDP echo applications to log just as we did in
@code{first.cc}, you will see similar output when you run the script.
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.415s)
Sent 1024 bytes to 10.1.2.4
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.2.4
@end verbatim
Recall that the first message, @code{Sent 1024 bytes to 10.1.2.4} is the
Recall that the first message, ``@code{Sent 1024 bytes to 10.1.2.4},'' is the
UDP echo client sending a packet to the server. In this case, the server
is on a different network (10.1.2.0). The second message, @code{Received 1024
bytes from 10.1.1.1}, is from the UDP echo server, generated when it receives
the echo packet. The final message, @code{Received 1024 bytes from 10.1.2.4}
is on a different network (10.1.2.0). The second message, ``@code{Received 1024
bytes from 10.1.1.1},'' is from the UDP echo server, generated when it receives
the echo packet. The final message, ``@code{Received 1024 bytes from 10.1.2.4},''
is from the echo client, indicating that it has received its echo back from
the server.
@@ -483,8 +484,8 @@ Node one knows it needs to send the packet to IP address 10.1.2.4, but it
doesn't know the MAC address of the corresponding node. It broadcasts on the
CSMA network (ff:ff:ff:ff:ff:ff) asking for the device that has IP address
10.1.2.4. In this case, the rightmost node replies saying it is at MAC address
00:00:00:00:00:06. (Note that node two is not directly involved in this
exchange, but is sniffing the network and reporting all of the traffic it sees.)
00:00:00:00:00:06. Note that node two is not directly involved in this
exchange, but is sniffing the network and reporting all of the traffic it sees.
This exchange is seen in the following lines,
@@ -559,8 +560,9 @@ devices set to four:
You should now see,
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.405s)
Sent 1024 bytes to 10.1.2.5
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.2.5
@@ -572,7 +574,7 @@ nodes, which is 10.1.2.5 instead of the default case, 10.1.2.4.
It is possible that you may not be satisfied with a trace file generated by
a bystander in the CSMA network. You may really want to get a trace from
a single device and you may not be interested in any other traffic on the
network. You can do this,
network. You can do this fairly easily/
Let's take a look at @code{scratch/mysecond.cc} and add that code enabling us
to be more specific. @code{ns-3} helpers provide methods that take a node
@@ -615,6 +617,14 @@ to the documentation for the @code{Node} class. If you now scroll down to the
documentation for the method. Using the @code{GetId} method can make
determining node numbers much easier in complex topologies.
Let's clear the old trace files out of the top-level directory to avoid confusion
about what is going on,
@verbatim
rm *.pcap
rm *.tr
@end verbatim
If you build the new script and run the simulation setting @code{nCsma} to 100,
@verbatim
@@ -624,8 +634,9 @@ If you build the new script and run the simulation setting @code{nCsma} to 100,
you will see the following output:
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.407s)
Sent 1024 bytes to 10.1.2.101
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.2.101
@@ -659,9 +670,27 @@ only packets that it receives are the ARP requests which are broadcast to the
entire CSMA network.
@verbatim
reading from file second-100-0.pcap, link-type EN10MB (Ethernet)
2.003696 arp who-has 10.1.2.101 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
2.003811 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.101
reading from file second-100-0.pcap, link-type EN10MB (Ethernet)
2.003696 arp who-has 10.1.2.101 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
2.003811 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.101
@end verbatim
Now take a look at the @code{tcpdump} for @code{second-101-0.pcap}.
@verbatim
tcpdump -nn -tt -r second-101-0.pcap
@end verbatim
You can now see that node 101 is really the participant in the echo exchange.
@verbatim
reading from file second-101-0.pcap, link-type EN10MB (Ethernet)
2.003696 arp who-has 10.1.2.101 (ff:ff:ff:ff:ff:ff) tell 10.1.2.1
2.003696 arp reply 10.1.2.101 is-at 00:00:00:00:00:67
2.003801 IP 10.1.1.1.49153 > 10.1.2.101.9: UDP, length 1024
2.003801 arp who-has 10.1.2.1 (ff:ff:ff:ff:ff:ff) tell 10.1.2.101
2.003822 arp reply 10.1.2.1 is-at 00:00:00:00:00:03
2.003822 IP 10.1.2.101.9 > 10.1.1.1.49153: UDP, length 1024
@end verbatim
@c ========================================================================
@@ -714,7 +743,6 @@ to the Wifi module and the mobility module which we will discuss below.
#include "ns3/simulator-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
#include "ns3/global-routing-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
@end verbatim
@@ -1035,14 +1063,15 @@ Since we have built an internetwork here, we need to enable internetwork routing
just as we did in the @code{second.cc} example script.
@verbatim
GlobalRouteManager::PopulateRoutingTables ();
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
@end verbatim
One thing that can surprise some users is the fact that the simulation we just
created will never ``naturally'' stop. This is because we asked the wireless
access point to generate beacons. It will generate beacons forever, so we must
tell the simulator to stop even though it may have beacon generation events
scheduled. The following line of code tells the simulator to stop so that
access point to generate beacons. It will generate beacons forever, and this
will result in simulator events being scheduled into the future indefinitely,
so we must tell the simulator to stop even though it may have beacon generation
events scheduled. The following line of code tells the simulator to stop so that
we don't simulate beacons forever and enter what is essentially an endless
loop.
@@ -1054,7 +1083,7 @@ We create just enough tracing to cover all three networks:
@verbatim
PointToPointHelper::EnablePcapAll ("third");
YansWifiPhyHelper::EnablePcap ("third", apDevices.Get (0));
phy.EnablePcap ("third", apDevices.Get (0));
CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
@end verbatim
@@ -1084,27 +1113,28 @@ repository you would type,
./waf --run scratch/mythird
@end verbatim
Since we have set up the UDP echo applications just as we did in the
Again, since we have set up the UDP echo applications just as we did in the
@code{second.cc} script, you will see similar output.
@verbatim
Entering directory `repos/ns-3-allinone-dev/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.407s)
Sent 1024 bytes to 10.1.2.4
Received 1024 bytes from 10.1.3.3
Received 1024 bytes from 10.1.2.4
@end verbatim
Recall that the first message, @code{Sent 1024 bytes to 10.1.2.4} is the
Recall that the first message, ``@code{Sent 1024 bytes to 10.1.2.4},'' is the
UDP echo client sending a packet to the server. In this case, the client
is on the wireless network (10.1.3.0). The second message,
@code{Received 1024 bytes from 10.1.3.3}, is from the UDP echo server,
``@code{Received 1024 bytes from 10.1.3.3},'' is from the UDP echo server,
generated when it receives the echo packet. The final message,
@code{Received 1024 bytes from 10.1.2.4} is from the echo client, indicating
``@code{Received 1024 bytes from 10.1.2.4},'' is from the echo client, indicating
that it has received its echo back from the server.
If you now go and look in the top level directory, you will find four trace
files, two from node zero and two from node one:
files from this simulation, two from node zero and two from node one:
@verbatim
third-0-0.pcap third-0-1.pcap third-1-0.pcap third-1-1.pcap
@@ -1223,8 +1253,8 @@ the discussion in @code{second.cc}. This is the same sequence.
Now, we spent a lot of time setting up mobility models for the wireless network
and so it would be a shame to finish up without even showing that the STA
nodes are actually moving around. Let's do this by hooking into the
@code{MobilityModel} course change trace source. This is usually considered
nodes are actually moving around during the simulation. Let's do this by hooking
into the @code{MobilityModel} course change trace source. This is usually considered
a fairly advanced topic, but let's just go for it.
As mentioned in the ``Tweaking ns-3'' section, the @command{ns-3} tracing system
@@ -1273,8 +1303,8 @@ like,
/NodeList/7/$ns3::MobilityModel/CourseChange
@end verbatim
Based on the discussion in the tracing section, you can easily infer that
this trace path references the seventh node in the NodeList. It specifies
Based on the discussion in the tracing section, you may infer that this trace
path references the seventh node in the global NodeList. It specifies
what is called an aggregated object of type @code{ns3::MobilityModel}. The
dollar sign prefix implies that the MobilityModel is aggregated to node seven.
The last component of the path means that we are hooking into the
@@ -1336,6 +1366,6 @@ any of these @code{Attributes} via the command line as we have previously
discussed.
We have just scratched the surface of @command{ns-3} in this tutorial, but we
hope we have covered enough to get you started doing useful work.
hope we have hopefully covered enough to get you started doing useful work.
-- The @command{ns-3} development team.

View File

@@ -110,7 +110,7 @@ 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. If the peripheral card implemented some networking function,
theys were called Network Interface Cards, or @emph{NICs}. Today most
they 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.
@@ -174,9 +174,10 @@ directory. Change into that release directory, and you should find a
directory structure something like the following:
@verbatim
AUTHORS examples/ README samples/ utils/ waf.bat*
build/ LICENSE regression/ scratch/ VERSION wscript
doc/ ns3/ RELEASE_NOTES src/ waf*
AUTHORS doc/ README RELEASE_NOTES utils/ wscript
bindings/ examples/ regression/ samples/ VERSION wutils.py
build/ LICENSE regression.py scratch/ waf* wutils.pyc
CHANGES.html ns3/ regression.pyc src/ waf.bat*
@end verbatim
@cindex first.cc
@@ -276,7 +277,7 @@ done a
@end verbatim
to build the project. So now if you look in the directory
@code{build/debug/ns3} you will find the four module include files shown
@code{../build/debug/ns3} you will find the four module include files shown
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.
@@ -310,16 +311,18 @@ 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 ``Doxygen
(ns-3-dev)'' in the navigation bar. If you select this link, you will be
taken to our documentation page.
taken to our documentation page for the current development release. There
is also a link to ``Doxygen (stable)'' that will take you to the documentation
for the latest stable release of @code{ns-3}.
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}
``book.'' If you expand @code{Modules} you will see a list of @command{ns-3}
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, expand the @code{Debugging} book and then
select the @code{Logging} page.
``book'' in the @code{ns-3} navigation tree. If you expand @code{Modules}
you will see a list of @command{ns-3} 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, 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 at the top of the page you will see the entry
@@ -437,7 +440,7 @@ high-level perspective the next line,
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
@end verbatim
tells the @code{PointToPointHelper} object to use the value ``5mbps''
tells the @code{PointToPointHelper} object to use the value ``5Mbps''
(five megabits per second) as the ``DataRate'' when it creates a
@code{PointToPointNetDevice} object.
@@ -492,7 +495,7 @@ helper are used to initialize the corresponding @code{Attributes} in the
created objects.
After executing the @code{pointToPoint.Install (nodes)} call we will have
two nodes, each with an installed point-to-point net device and a
two nodes, each with an installed point-to-point net device and a single
point-to-point channel between them. Both devices will be configured to
transmit data at five megabits per second over the channel which has a two
millisecond transmission delay.
@@ -576,13 +579,13 @@ created.
The first line of code in the above snippet declares the
@code{UdpEchoServerHelper}. As usual, this isn't the application itself, it
is an object used to help us create the actual applications. One of our
conventions is to place required @code{Attributes} in the helper constructor.
conventions is to place @emph{required} @code{Attributes} in the helper constructor.
In this case, the helper can't do anything useful unless it is provided with
a port number that the client also knows about. Rather than just picking one
and hoping it all works out, we require the port number as a parameter to the
constructor. The constructor, in turn, simply does a @code{SetAttribute}
with the passed value. You can, if desired, set the ``Port'' @code{Attribute}
to another value later.
with the passed value. If you want, you can set the ``Port'' @code{Attribute}
to another value later using @code{SetAttribute}.
Similar to many other helper objects, the @code{UdpEchoServerHelper} object
has an @code{Install} method. It is the execution of this method that actually
@@ -591,7 +594,11 @@ to a node. Interestingly, the @code{Install} method takes a
@code{NodeContainter} as a parameter just as the other @code{Install} methods
we have seen. This is actually what is passed to the method even though it
doesn't look so in this case. There is a C++ @emph{implicit conversion} at
work here.
work here that takes the result of @code{nodes.Get (1)} (which returns a smart
pointer to a node object --- @code{Ptr<Node>}) and uses that in a constructor
for an unnamed @code{NodeContainer} that is then passed to @code{Install}.
If you are ever at a loss to find a particular method signature in C++ code
that compiles and runs just fine, look for these kinds of implicit conversions.
We now see that @code{echoServer.Install} is going to install a
@code{UdpEchoServerApplication} on the node found at index number one of the
@@ -603,9 +610,12 @@ helper.
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,
methods take @code{Time} parameters. In this case, we use an @emph{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. Be aware that
the conversion rules may be controlled by the model author, and C++ has its
own rules, so you can't always just assume that parameters will be happily
converted for you. The two lines,
@verbatim
serverApps.Start (Seconds (1.0));
@@ -614,9 +624,9 @@ conversion sequence to take the C++ double 1.0 and convert it to an
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 (the application stop event) to be executed at ten seconds,
the simulation will last at least ten seconds.
into the simulation. By virtue of the fact that we have declared a simulation
event (the application stop event) to be executed at ten seconds, the simulation
will last @emph{at least} ten seconds.
@subsubsection UdpEchoClientHelper
@@ -682,25 +692,27 @@ When we previously called the methods,
@end verbatim
we actually scheduled events in the simulator at 1.0 seconds, 2.0 seconds and
10.0 seconds. When @code{Simulator::Run} is called, the system will begin
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 application will begin the data transfer phase of the
simulation by sending a packet to the server.
two events at 10.0 seconds. When @code{Simulator::Run} is called, the system
will begin 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 (this event may, in turn, schedule many other events). Then it
will run the event scheduled for t=2.0 seconds which will start the echo client
application. Again, this event may schedule many more events. The start event
implementation in 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
that will be automatically scheduled behind the scenes 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
Eventually, since we only send one packet (recall the @code{MaxPackets}
@code{Attribute} was set to one), the chain of events triggered by
that single client echo request will taper off and the simulation will go
idle. Once this happens, the remaining events will be the @code{Stop} events
for the server and the client. When these events are executed, there are
no further events to process and @code{Simulator::Run} returns. The simulation
is complete.
is then complete.
All that remains is to clean up. This is done by calling the global function
@code{Simulator::Destroy}. As the helper functions (or low level
@@ -721,10 +733,11 @@ took care of the hard part for you. The remaining lines of our first
We have made it trivial to build your simple scripts. All you have to do is
to drop your script into the scratch directory and it will automatically be
built if you run Waf. Let's try it. Copy @code{examples/first.cc} into
the @code{scratch} directory.
the @code{scratch} directory after changing back into the top level directory.
@verbatim
~/repos/ns-3-dev > cp examples/first.cc scratch/myfirst.cc
cd ..
cp examples/first.cc scratch/myfirst.cc
@end verbatim
Now build your first example script using waf:
@@ -737,10 +750,11 @@ You should see messages reporting that your @code{myfirst} example was built
successfully.
@verbatim
Entering directory `repos/ns-3-allinone-dev/ns-3-dev/build'
[563/648] cxx: scratch/myfirst.cc -> build/debug/scratch/myfirst_3.o
[646/648] cxx_link: build/debug/scratch/myfirst_3.o -> build/debug/scratch/myfirst
Build finished successfully (00:00:02)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
[614/708] cxx: scratch/myfirst.cc -> build/debug/scratch/myfirst_3.o
[706/708] cxx_link: build/debug/scratch/myfirst_3.o -> build/debug/scratch/myfirst
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (2.357s)
@end verbatim
You can now run the example (note that if you build your program in the scratch
@@ -753,8 +767,9 @@ directory you must run it out of the scratch directory):
You should see some output:
@verbatim
Entering directory `repos/ns-3-allinone-dev/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.418s)
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
@@ -778,49 +793,57 @@ packet back from the server.
Now that you have used some of the @command{ns-3} helpers you may want to
have a look at some of the source code that implements that functionality.
The most recent code can be browsed on our web server at the following link:
@uref{http://code.nsnam.org/?sort=lastchange}. If you click on the bold
repository names on the left of the page, you will see @emph{changelogs} for
these repositories, and links to the @emph{manifest}. From the manifest
links, one can browse the source tree.
@uref{http://code.nsnam.org/ns-3-dev}. There, you will see the Mercurial
summary page for our @command{ns-3} development tree.
The top-level directory for one of our @emph{repositories} will look
something like:
At the top of the page, you will see a number of links,
@verbatim
drwxr-xr-x [up]
drwxr-xr-x bindings python files
drwxr-xr-x doc files
drwxr-xr-x examples files
drwxr-xr-x ns3 files
drwxr-xr-x regression files
drwxr-xr-x samples files
drwxr-xr-x scratch files
drwxr-xr-x src files
drwxr-xr-x utils files
-rw-r--r-- 2009-03-24 00:51 -0700 505 .hgignore file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 1682 .hgtags file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 686 AUTHORS file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 14893 CHANGES.html file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 17987 LICENSE file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 3742 README file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 13505 RELEASE_NOTES file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 6 VERSION file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 9257 regression.py file | revisions | annotate
-rwxr-xr-x 2009-03-24 00:51 -0700 81285 waf file | revisions | annotate
-rwxr-xr-x 2009-03-24 00:51 -0700 28 waf.bat file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 26270 wscript file | revisions | annotate
-rw-r--r-- 2009-03-24 00:51 -0700 6636 wutils.py file | revisions | annotate
summary | shortlog | changelog | graph | tags | files
@end verbatim
Go ahead and select the @code{files} link. This is what the top-level of
most of our @emph{repositories} will look:
@verbatim
drwxr-xr-x [up]
drwxr-xr-x bindings python files
drwxr-xr-x doc files
drwxr-xr-x examples files
drwxr-xr-x ns3 files
drwxr-xr-x regression files
drwxr-xr-x samples files
drwxr-xr-x scratch files
drwxr-xr-x src files
drwxr-xr-x utils files
-rw-r--r-- 2009-07-01 12:47 +0200 560 .hgignore file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1886 .hgtags file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1276 AUTHORS file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 30961 CHANGES.html file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 17987 LICENSE file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 3742 README file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 16171 RELEASE_NOTES file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 6 VERSION file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 10946 regression.py file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 88110 waf file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 28 waf.bat file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 35395 wscript file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 7673 wutils.py file | revisions | annotate
@end verbatim
Our example scripts are in the @code{examples} directory. If you click on @code{examples}
you will see a list of files. One of the files in that directory is @code{first.cc}. If
you click on @code{first.cc} you will find the code you just walked through.
The source code is mainly in the @code{src} directory. You can view source
code either by clicking on the directory name or by clicking on the @code{files}
link to the right of the directory name. If you click on the @code{src}
directory, you will be taken to the listing of the @code{src} subdirectories. If you
click on @code{core} subdirectory, you will find a list of files. The first file
you will find (as of this writing) is @code{abort.h}. If you
click on @code{abort.h} link, you will be sent to the source file for @code{abort.h}.
then click on @code{core} subdirectory, you will find a list of files. The first file
you will find (as of this writing) is @code{abort.h}. If you click on the
@code{abort.h} link, you will be sent to the source file for @code{abort.h} which
contains useful macros for exiting scripts if abnormal conditions are detected.
Our example scripts are in the @code{examples} directory. The source code for
the helpers we have used in this chapter can be found in the
The source code for the helpers we have used in this chapter can be found in the
@code{src/helper} directory. Feel free to poke around in the directory tree to
get a feel for what is there and the style of @command{ns-3} programs.

View File

@@ -80,7 +80,7 @@ following displayed,
adding changesets
adding manifests
adding file changes
added 26 changesets with 40 changes to 7 files
added 31 changesets with 45 changes to 7 files
7 files updated, 0 files merged, 0 files removed, 0 files unresolved
@end verbatim
@@ -126,8 +126,8 @@ introduced features.
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.4 and
ns-3.4-ref-traces) in the text below. You can find the latest version of the
string ``ns-3-dev'' with your choice of release (e.g., ns-3.5 and
ns-3.5-ref-traces) 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
@uref{http://www.nsnam.org/getting_started.html,,``Getting Started''}
web page and looking for the latest release identifier.
@@ -138,13 +138,23 @@ script to pull down the various pieces of @command{ns-3} you will be using.
Go ahead and type the following into your shell (remember you can substitute
the name of your chosen release number instead of @code{ns-3-dev} -- like
@code{"ns-3.4"} and @code{"ns-3.4-ref-traces"} if you want to work with a
@code{"ns-3.5"} and @code{"ns-3.5-ref-traces"} if you want to work with a
stable release).
@verbatim
./download.py -n ns-3-dev -r ns-3-dev-ref-traces
@end verbatim
Note that the default for the @code{-n} option is @code{ns-3-dev} and the
default for the @code{-r} option is @code{ns-3-dev-ref-traces} and so the
above is actually redundant. We provide this example to illustrate how to
specify alternate repositories. In order to download @code{ns-3-dev} you
can actually use the defaults and simply type,
@verbatim
./download.py
@end verbatim
As the hg (Mercurial) command executes, you should see something like the
following,
@@ -152,15 +162,15 @@ following,
#
# Get NS-3
#
Cloning ns-3 branch
=> hg clone http://code.nsnam.org/ns-3-dev ns-3-dev
requesting all changes
adding changesets
adding manifests
adding file changes
added 4292 changesets with 15368 changes to 1671 files
823 files updated, 0 files merged, 0 files removed, 0 files unresolved
added 4634 changesets with 16500 changes to 1762 files
870 files updated, 0 files merged, 0 files removed, 0 files unresolved
@end verbatim
This is output by the download script as it fetches the actual @code{ns-3}
@@ -177,8 +187,8 @@ code from the repository. Next, you should see something like,
adding changesets
adding manifests
adding file changes
added 79 changesets with 1102 changes to 222 files
206 files updated, 0 files merged, 0 files removed, 0 files unresolved
added 86 changesets with 1178 changes to 259 files
208 files updated, 0 files merged, 0 files removed, 0 files unresolved
@end verbatim
This is the download script fetching the reference trace files for you.
@@ -191,10 +201,10 @@ continue with something like,
#
# Get PyBindGen
#
Required pybindgen version: 0.10.0.630
Required pybindgen version: 0.10.0.640
Trying to fetch pybindgen; this will fail if no network connection is available. Hit Ctrl-C to skip.
=> bzr checkout -rrevno:630 https://launchpad.net/pybindgen pybindgen
=> bzr checkout -rrevno:640 https://launchpad.net/pybindgen pybindgen
Fetch was successful.
@end verbatim
@@ -205,7 +215,7 @@ Next you should see (modulo platform variations) something along the lines of,
#
# Get NSC
#
Required NSC version: nsc-0.5.0
Retrieving nsc from https://secure.wand.net.nz/mercurial/nsc
=> hg clone https://secure.wand.net.nz/mercurial/nsc nsc
@@ -213,8 +223,8 @@ Next you should see (modulo platform variations) something along the lines of,
adding changesets
adding manifests
adding file changes
added 270 changesets with 17375 changes to 14991 files
10614 files updated, 0 files merged, 0 files removed, 0 files unresolved
added 273 changesets with 17565 changes to 15175 files
10622 files updated, 0 files merged, 0 files removed, 0 files unresolved
@end verbatim
This part of the process is the script downloading the Network Simulation
@@ -257,16 +267,16 @@ get a copy of a release by typing the following into your Linux shell
cd
mkdir tarballs
cd tarballs
wget http://www.nsnam.org/releases/ns-allinone-3.4.tar.bz2
tar xjf ns-allinone-3.4.tar.bz2
wget http://www.nsnam.org/releases/ns-allinone-3.5.tar.bz2
tar xjf ns-allinone-3.5.tar.bz2
@end verbatim
If you change into the directory @code{ns-allinone-3.4} you should see a
If you change into the directory @code{ns-allinone-3.5} you should see a
number of files:
@verbatim
build.py* ns-3.4/ nsc-0.5.0/ README
constants.py ns-3.4-ref-traces/ pybindgen-0.10.0.630/ util.py
build.py* ns-3.5/ nsc-0.5.0/ README
constants.py ns-3.5-ref-traces/ pybindgen-0.10.0.640/ util.py
@end verbatim
You are now ready to build the @command{ns-3} distribution.
@@ -288,7 +298,7 @@ Change into the directory you created in the download section above. If you
downloaded using Mercurial you should have a directory called
@code{ns-3-allinone} under your @code{~/repos} directory. If you downloaded
using a tarball you should have a directory called something like
@code{ns-3-allinone-3.4} under your @code{~/tarballs} directory. Take a deep
@code{ns-allinone-3.5} under your @code{~/tarballs} directory. Take a deep
breath and type the following:
@verbatim
@@ -300,13 +310,13 @@ script builds the various pieces you downloaded. Eventually you should see the
following magic words:
@verbatim
Build finished successfully (00:02:37)
Leaving directory `./ns-3-dev'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (2m30.586s)
@end verbatim
Once the project has built you can say goodbye to your old friends, the
@code{ns-3-allinone} scripts. You got what you needed from them and will now
interact directly with Waf and we do it in the @code{ns-3-dev} directory and
interact directly with Waf and we do it in the @code{ns-3-dev} directory,
not in the @code{ns-3-allinone} directory. Go ahead and change into the
@code{ns-3-dev} directory (or the directory for the appropriate release you
downloaded.
@@ -340,76 +350,72 @@ for you). As the build system checks for various dependencies you should see
output that looks similar to the following,
@verbatim
Checking for program g++ : ok /usr/bin/g++
Checking for program cpp : ok /usr/bin/cpp
Checking for program ar : ok /usr/bin/ar
Checking for program ranlib : ok /usr/bin/ranlib
Checking for g++ : ok
Checking for program pkg-config : ok /usr/bin/pkg-config
Checking for regression reference traces : ok ../ns-3-dev-ref-traces (guessed)
Checking for -Wno-error=deprecated-declarations support : yes
Checking for header stdlib.h : ok
Checking for header signal.h : ok
Checking for header pthread.h : ok
Checking for high precision time implementation : 128-bit integer
Checking for header stdint.h : ok
Checking for header inttypes.h : ok
Checking for header sys/inttypes.h : not found
Checking for library rt : ok
Checking for header netpacket/packet.h : ok
Checking for header linux/if_tun.h : ok
Checking for pkg-config flags for GTK_CONFIG_STORE : ok
Package libxml-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `libxml-2.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libxml-2.0' found
Checking for pkg-config flags for LIBXML2 : not found
Checking for library sqlite3 : ok
Checking for NSC location : ok ../nsc (guessed)
Checking for library dl : ok
Checking for NSC supported architecture x86_64 : ok
Package goocanvas was not found in the pkg-config search path.
Perhaps you should add the directory containing `goocanvas.pc'
to the PKG_CONFIG_PATH environment variable
No package 'goocanvas' found
Checking for pkg-config flags for MOBILITY_VISUALIZER : not found
Checking for program python : ok /usr/bin/python
Checking for Python version >= 2.3 : ok 2.5.2
Checking for library python2.5 : ok
Checking for program python2.5-config : ok /usr/bin/python2.5-config
Checking for header Python.h : ok
Checking for -fvisibility=hidden support : yes
Checking for pybindgen location : ok ../pybindgen (guessed)
Checking for Python module pybindgen : ok
Checking for pybindgen version : ok 0.10.0.630
Checking for Python module pygccxml : ok
Checking for pygccxml version : ok 0.9.5
Checking for program gccxml : ok /usr/local/bin/gccxml
Checking for gccxml version : ok 0.9.0
Checking for program sudo : ok /usr/bin/sudo
Checking for program hg : ok /usr/bin/hg
Checking for program valgrind : ok /usr/bin/valgrind
---- Summary of optional NS-3 features:
Threading Primitives : enabled
Real Time Simulator : enabled
Emulated Net Device : enabled
Tap Bridge : enabled
GtkConfigStore : enabled
XmlIo : not enabled (library 'libxml-2.0 >= 2.7' not found)
SQlite stats data output : enabled
Network Simulation Cradle : enabled
Python Bindings : enabled
Python API Scanning Support : enabled
Use sudo to set suid bit : not enabled (option --enable-sudo not selected)
Configuration finished successfully (00:00:02); project is now ready to build.
Checking for program g++ : ok /usr/bin/g++
Checking for program cpp : ok /usr/bin/cpp
Checking for program ar : ok /usr/bin/ar
Checking for program ranlib : ok /usr/bin/ranlib
Checking for g++ : ok
Checking for program pkg-config : ok /usr/bin/pkg-config
Checking for regression reference traces : ok ../ns-3-dev-ref-traces (guessed)
Checking for -Wno-error=deprecated-declarations support : yes
Checking for -Wl,--soname=foo support : yes
Checking for header stdlib.h : ok
Checking for header signal.h : ok
Checking for header pthread.h : ok
Checking for high precision time implementation : 128-bit integer
Checking for header stdint.h : ok
Checking for header inttypes.h : ok
Checking for header sys/inttypes.h : not found
Checking for library rt : ok
Checking for header netpacket/packet.h : ok
Checking for pkg-config flags for GSL : ok
Checking for header linux/if_tun.h : ok
Checking for pkg-config flags for GTK_CONFIG_STORE : ok
Checking for pkg-config flags for LIBXML2 : ok
Checking for library sqlite3 : ok
Checking for NSC location : ok ../nsc (guessed)
Checking for library dl : ok
Checking for NSC supported architecture x86_64 : ok
Checking for program python : ok /usr/bin/python
Checking for Python version >= 2.3 : ok 2.5.2
Checking for library python2.5 : ok
Checking for program python2.5-config : ok /usr/bin/python2.5-config
Checking for header Python.h : ok
Checking for -fvisibility=hidden support : yes
Checking for pybindgen location : ok ../pybindgen (guessed)
Checking for Python module pybindgen : ok
Checking for pybindgen version : ok 0.10.0.640
Checking for Python module pygccxml : ok
Checking for pygccxml version : ok 0.9.5
Checking for program gccxml : ok /usr/local/bin/gccxml
Checking for gccxml version : ok 0.9.0
Checking for program sudo : ok /usr/bin/sudo
Checking for program hg : ok /usr/bin/hg
Checking for program valgrind : ok /usr/bin/valgrind
---- Summary of optional NS-3 features:
Threading Primitives : enabled
Real Time Simulator : enabled
Emulated Net Device : enabled
GNU Scientific Library (GSL) : enabled
Tap Bridge : enabled
GtkConfigStore : enabled
XmlIo : enabled
SQlite stats data output : enabled
Network Simulation Cradle : enabled
Python Bindings : enabled
Python API Scanning Support : enabled
Use sudo to set suid bit : not enabled (option --enable-sudo not selected)
Static build : not enabled (option --enable-static not selected)
'configure' finished successfully (2.870s)
@end verbatim
Note the last part of the above output. Some ns-3 options are not enabled by
default or require support from the underlying system to work properly.
For instance, to enable XmlTo, the library libxml-2.0 must be found on the
system. in the example above, this library was not found and the corresponding
feature was not enabled. There is a feature to use sudo to set the suid bit of
certain programs. This was not enabled by default.
system. If this library were not found, the corresponding @command{ns-3} feature
would not be enabled and a message would be displayed. Note further that there is
a feature to use the progarm @code{sudo} to set the suid bit of certain programs.
This is not enabled by default and so this feature is reported as ``not enabled.''
Now go ahead and switch back to the debug build.
@@ -427,15 +433,15 @@ the @command{ns-3} programs by simply typing,
Some waf commands are meaningful during the build phase and some commands are valid
in the configuration phase. For example, if you wanted to use the emulation
features of @command{ns-3} you might want to enable setting the suid bit using
sudo. This is a configuration command, and so you could have run the following
command
sudo as described above. This turns out to be a configuration-time command, and so
you could reconfigure using the following command
@verbatim
./waf -d debug --enable-sudo configure
@end verbatim
If you had done this, waf would have run sudo to change the socket creator
programs to run as root. There are many other configure- and build-time options
If you do this, waf will have run sudo to change the socket creator programs of the
emulation code to run as root. There are many other configure- and build-time options
available in waf. To explore these options, type:
@verbatim
@@ -462,26 +468,45 @@ You can run the unit tests of the @command{ns-3} distribution by running the
./waf --check
@end verbatim
You should see a report from each unit test that executes indicating that the
test has passed.
These tests are run in parallel by waf, so the summary, ``Ran n tests'' will
appear as soon as all of the tasks are launched, but you should eventually
see a report saying that,
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
-- Running NS-3 C++ core unit tests...
PASS AddressHelper
PASS Wifi
PASS DcfManager
...
PASS Object
PASS Ptr
PASS Callback
-- Running NS-3 Python bindings unit tests...
C++ UNIT TESTS: all 33 tests passed.
@end verbatim
This is the important message.
You will also see output from the test runner and waf task sequence numbers
the output will actually look something like,
@verbatim
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
[707/709] get-unit-tests-list
[708/709] run-python-unit-tests
[709/709] print-introspected-doxygen
[710/743] run-unit-test(AddressHelper)
[711/743] run-unit-test(Wifi)
...........
----------------------------------------------------------------------
Ran 11 tests in 0.003s
OK
[712/743] run-unit-test(DcfManager)
[713/743] run-unit-test(MacRxMiddle)
[714/743] run-unit-test(Ipv4ListRouting)
...
[739/743] run-unit-test(RandomVariable)
[740/743] run-unit-test(Object)
[741/743] run-unit-test(Ptr)
[742/743] run-unit-test(Callback)
[743/743] collect-unit-tests-results
C++ UNIT TESTS: all 33 tests passed.
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (1.799s)
@end verbatim
This command is typically run by @code{users} to quickly verify that an
@@ -491,10 +516,10 @@ This command is typically run by @code{users} to quickly verify that an
You can also run our regression test suite to ensure that your distribution and
toolchain have produced binaries that generate output that is identical to
known-good reference output files. You downloaded these reference traces to
your machine during the download process above. (Warning: The @code{ns-3.2}
and @code{ns-3.3} releases do not use the @code{ns-3-allinone} environment
and require you to be online when you run regression tests because they
dynamically synchronize the reference traces directory with an online
your machine during the @code{./download.py} process above. (Warning: The
@code{ns-3.2} and @code{ns-3.3} releases do not use the @code{ns-3-allinone}
environment and require you to be online when you run regression tests because
hey dynamically synchronize the reference traces directory with an online
repository immediately prior to the run).
During regression testing Waf will run a number of tests that generate what we
@@ -509,6 +534,9 @@ to convert the pcap files to text using tcpdump prior to comparison.
Some regression tests may be SKIPped if the required support
is not present.
Note that the regression tests are also run in parallel and so the messages
may be interleaved.
To run the regression tests, you provide Waf with the regression flag.
@verbatim
@@ -530,7 +558,8 @@ passing.
...
Regression testing summary:
PASS: 22 of 22 tests passed
Build finished successfully (00:00:23)
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (25.826s)
@end verbatim
If you want to take a look at an example of what might be checked during

View File

@@ -75,7 +75,7 @@ or in Python. The results of some simulations can be visualized by
generates pcap packet trace files, other utilities can be used to
analyze traces as well.
In this tutorial, we will first concentrate on scripting
directly in C++ and interpreting results via ascii trace files.
directly in C++ and interpreting results via trace files.
But there are similarities as well (both, for example, are based on C++
objects, and some code from ns-2 has already been ported to @command{ns-3}).
@@ -256,8 +256,8 @@ for development. A
software toolchain is the set of programming tools available in the given
environment. For a quick review of what is included in the GNU toolchain see,
@uref{http://en.wikipedia.org/wiki/GNU_toolchain}. @command{ns-3} uses gcc,
GNU binutils, and gdb. However, we do not use the GNU build system,
either make or autotools, using Waf instead.
GNU binutils, and gdb. However, we do not use the GNU build system tools,
neither make nor autotools. We use Waf for these functions.
@cindex Linux
Typically an @command{ns-3} author will work in Linux or a Linux-like
@@ -265,11 +265,11 @@ environment. For those running under Windows, there do exist environments
which simulate the Linux environment to various degrees. The @command{ns-3}
project supports development in the Cygwin environment for
these users. See @uref{http://www.cygwin.com/}
for details on downloading (MinGW is presently not supported).
Cygwin provides many of the popular Linux system commands.
It can, however, sometimes be problematic due to the way it actually does its
emulation, and sometimes interactions with other Windows software can cause
problems.
for details on downloading (MinGW is presently not officially supported,
although some of the project maintainers to work with it). Cygwin provides
many of the popular Linux system commands. It can, however, sometimes be
problematic due to the way it actually does its emulation, and sometimes
interactions with other Windows software can cause problems.
@cindex Cygwin
@cindex MinGW

View File

@@ -89,7 +89,8 @@ that knowledge to get some interesting information out of the
@subsection Enabling Logging
@cindex NS_LOG
Let's use the NS_LOG environment variable to turn on some more logging, but
to get our bearings, go ahead and run the script just as you did previously,
first, just to get our bearings, go ahead and run the last script just as you
did previously,
@verbatim
./waf --run scratch/myfirst
@@ -99,8 +100,9 @@ You should see the now familiar output of the first @command{ns-3} example
program
@verbatim
Entering directory `repos/ns-3-dev/build'
Compilation finished successfully
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.413s)
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2
@@ -148,15 +150,17 @@ you run the script with NS_LOG set this way, the @command{ns-3} logging
system will pick up the change and you should see the following output:
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x638180, 0x6389b0)
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
@@ -186,7 +190,7 @@ logging component name from the class name.
It turns out that in some cases, it can be hard to determine which method
actually generates a log message. If you look in the text above, you may
wonder where the string ``@code{Received 1024 bytes from 10.1.1.2}'' comes
from. You can resolve this by ORing the @code{prefix_func} level into the
from. You can resolve this by OR'ing the @code{prefix_func} level into the
@code{NS_LOG} environment variable. Try doing the following,
@verbatim
@@ -201,15 +205,17 @@ that every message from the given log component is prefixed with the component
name.
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x638180, 0x6389b0)
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
@@ -236,10 +242,12 @@ echo client and server applications. You may see that this can be very useful
in debugging problems.
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
@@ -247,7 +255,7 @@ in debugging problems.
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
UdpEchoServerApplication:HandleRead(): Echoing packet
UdpEchoClientApplication:HandleRead(0x638320, 0x638b50)
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
@@ -269,10 +277,12 @@ Again, you will have to remove the newline above. If you run the script now,
you should see the following output:
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.418s)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
@@ -280,7 +290,7 @@ you should see the following output:
2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x638490, 0x638cc0)
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
@@ -292,22 +302,22 @@ you should see the following output:
You can see that the constructor for the UdpEchoServer was called at a
simulation time of 0 seconds. This is actually happening before the
simulation starts. The same for the UdpEchoClient constructor.
simulation starts, but the time is displayed as zero seconds. The same is true
for the UdpEchoClient constructor message.
Recall that the @code{scratch/first.cc} script started the echo server
application at one second into the simulation. You can now see that the
@code{StartApplication} method of the server is, in fact, called at one second
(or one billion nanoseconds). You can also see that the echo client
application is started at a simulation time of two seconds as we requested in
the script.
@code{StartApplication} method of the server is, in fact, called at one second.
You can also see that the echo client application is started at a simulation
time of two seconds as we requested in the script.
You can now follow the progress of the simulation from the
@code{ScheduleTransmit} call in the client that calls @code{Send} to the
@code{HandleRead} callback in the echo server application. Note that the
elapsed time as the packet is sent across the point-to-point link is 3.6864
elapsed time for the packet to be sent across the point-to-point link is 3.69
milliseconds. You see the echo server logging a message telling you that it
has echoed the packet and then, after a delay, you see the echo client receive
the echoed packet in its @code{HandleRead} method.
has echoed the packet and then, after another channel delay, you see the echo
client receive the echoed packet in its @code{HandleRead} method.
There is a lot that is happening under the covers in this simulation that you
are not seeing as well. You can very easily follow the entire process by
@@ -320,7 +330,7 @@ turning on all of the logging components in the system. Try setting the
The asterisk above is the logging component wildcard. This will turn on all
of the logging in all of the components used in the simulation. I won't
reproduce the output here (as of this writing it produces 974 lines of output
reproduce the output here (as of this writing it produces 1265 lines of output
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,
@@ -328,15 +338,16 @@ and look through it with your favorite editor if you like,
./waf --run scratch/myfirst > log.out 2>&1
@end verbatim
I personally use this volume of logging quite a bit when I am presented with
a problem and I have no idea where things are going wrong. I can follow the
I personally use this extremely verbose version of logging when I am presented
with a problem and I have no idea where things are going wrong. I can follow the
progress of the code quite easily without having to set breakpoints and step
through code in a debugger. When I have a general idea about what is going
wrong, I transition into a debugger for fine-grained examination of the
problem. This kind of output can be especially useful when your script does
something completely unexpected. If you are stepping using a debugger you
may miss an unexpected excursion completely. Logging the excursion makes it
quickly visible.
through code in a debugger. I can just edit up the output in my favorite editor
and search around for things I expect, and see things happening that I don't
expect. When I have a general idea about what is going wrong, I transition into
a debugger for a fine-grained examination of the problem. This kind of output
can be especially useful when your script does something completely unexpected.
If you are stepping using a debugger you may miss an unexpected excursion
completely. Logging the excursion makes it quickly visible.
@node Adding Logging to your Code
@subsection Adding Logging to your Code
@@ -399,8 +410,9 @@ If you now run the script you will see your new ``Creating Topology'' log
message,
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.404s)
Creating Topology
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
@@ -453,8 +465,11 @@ sort out which program gets which argument. The command line parser will
now see the @code{--PrintHelp} argument and respond with,
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Handle arg name=PrintHelp value=
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
@@ -527,7 +542,9 @@ time prefix.
If you run the script, you should now see the following output,
@verbatim
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.405s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
@@ -589,8 +606,9 @@ in which case we recover the timing we had when we explicitly set the
@code{DataRate} and @code{Delay} in the script:
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/bu
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/bui
'build' finished successfully (0.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
@@ -608,13 +626,13 @@ In particular we could set the @code{UdpEchoClient Attribute MaxPackets}
to some other value than one.
How would you go about that? Give it a try. Remember you have to comment
out the place we override the default @code{Attribute} in the script. Then you
have to rebuild the script using the default. You will also have to find the
syntax for actually setting the new default atribute value using the command
line help facility. Once you have this figured out you should be able to
control the number of packets echoed from the command line. Since we're nice
folks, we'll tell you that your command line should end up looking something
like,
out the place we override the default @code{Attribute} and explicitly set
@code{MaxPackets} in the script. Then you have to rebuild the script. You
will also have to find the syntax for actually setting the new default atribute
value using the command line help facility. Once you have this figured out
you should be able to control the number of packets echoed from the command
line. Since we're nice folks, we'll tell you that your command line should
end up looking something like,
@verbatim
./waf --run "scratch/myfirst
@@ -666,8 +684,9 @@ Try,
@end verbatim
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.403s)
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
@@ -688,8 +707,9 @@ setting the @code{--nPackets} argument in the command line,
You should now see
@verbatim
Entering directory `repos/ns-3-allinone/ns-3-dev/build'
Build finished successfully (00:00:00)
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone-3.5-tutorial/ns-3-dev/build'
'build' finished successfully (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
@@ -705,7 +725,7 @@ You should now see
UdpEchoServerApplication:~UdpEchoServer()
@end verbatim
You have now echoed two packets.
You have now echoed two packets. Pretty easy, isn't it?
You can see that if you are an @command{ns-3} user, you can use the command
line argument system to control global values and @code{Attributes}. If you are
@@ -827,7 +847,7 @@ You can now build the script and run it from the command line:
@cindex myfirst.tr
Just as you have seen many times before, you will see some messages from Waf and then
the ``Build finished successfully'' with some number of messages from
``'build' finished successfully'' with some number of messages from
the running program.
When it ran, the program will have created a file named @code{myfirst.tr}.