HOWTO make and use a new application

From Nsnam
Revision as of 20:41, 13 May 2009 by Craigdo (Talk | contribs) (HOWTO make and use a new application)

Jump to: navigation, search

Main Page - Current Development - Developer FAQ - Tools - Related Projects - Project Ideas - Summer Projects

Installation - Troubleshooting - User FAQ - HOWTOs - Samples - Models - Education - Contributed Code - Papers

One of the easiest ways a person can change the behavior of ns-3 is by writing an application. In this HOWTO, we clone the existing UDP Echo application and associated example script. We change the client behavior by changing attributes in the new script; and we change server behavior by adding a new attribute to the server application and change how the server responds to requests. We use the new server attribute in the script. The resulting behavior (simulating a trivial request-response exchange) is verified in the pcap traces.

HOWTO make and use a new application

1. Clone, build and tests an ns-3 release to use as a clean starting point (this is actually out-of-date -- you should now use ns-3-allinone to accomplish the same thing)

   a.  hg clone http://code@nsnam.org/ns-3-dev ns-3-my-new-app
   b.  cd ns-3-my-new-app
   c.  ./waf -d debug configure
   d.  ./waf
   e.  ./waf check
   f.  ./waf --regression

2. Copy the UDP Echo applications into a new place to use as a starting point

   a.  cd src/applications
   b.  cp -r udp-echo request-response
   c.  cd request-response
   d.  mv udp-echo-client.h request-response-client.h
   e.  mv udp-echo-client.cc request-response-client.cc
   f.  mv udp-echo-server.h request-response-server.h
   g.  mv udp-echo-server.cc request-response-server.cc

3. Change the names to protect the innocent (not all changes below will affect every file)

   a.  Edit (emacs) the request-response-client.h file you just made
   b.  replace-string UdpEcho with RequestResponse
   c.  replace-string UDP_ECHO with REQUEST_RESPONSE
   d.  replace-string udp-echo with request-response
   e.  replace-string udpecho with requestresponse
   f.  replace-string Udp Echo with Request Response
   g.  save file
   h.  repeat for request-response-client.cc
   i.  repeat for request-response-server.h    
   j.  repeat for request-response-server.cc

4. Tell waf how to build the new applications

   a.  edit (emacs) wscript
   b.  replace-string udp-echo with request-response
   c.  save file
   d.  edit ns-3-my-new-app/src/wscript
   e.  find the string 'applications/udp-echo' in the all_modules assignment
   f.  copy that line to a new one and change udp-echo to request-response
       'applications/udp-echo',
       'applications/request-response',

5. Build the new applications

   a.  ./waf

6. Make a new helper for your new application

   a.  cd ns-3-my-new-app/src/helper
   b.  cp udp-echo-helper.cc request-response-helper.cc
   c.  cp udp-echo-helper.h request-response-helper.h
   d.  Edit the new helper files and make the same substitutions as in step 3 
       above.
   e.  Edit the helper wscript file and add entries for your new helper files.
       Add the string "'request-response'," just before the first instance of udp-echo in create_ns3_module
       Add a line, 'request-response-helper.cc', in the helper.source assignments
       Add a line, 'request-response-helper.h', in the headers.source assignments

7. Build the new helper

   a.  ./waf

8. Make and build a new script to use the new application and helper

   a.  cp ns-3-my-new-app/examples/udp-echo.cc ns-3-my-new-app/scratch/request-response.cc
   b.  Edit the new script in the scratch directory and make the same substitutions as in step 3 above.
   c.  Go to the top-level directory (one above scratch/) and execute ./waf (which will automatically pick 
       up the new source file in scratch/)

9. Run your new script, application and helper

   a.  ./waf --run scratch/request-response

10. Observe new ASCII trace and pcap trace files in the top-level directory

You have now duplicated everything you need and can now get down to the business of making your new application do what you want. Let's just make a simple change to have the client send a small request packet to which the server replies with a big hunk of data.

1. Change the client application behavior

   a.  cd src/applications/request-response/
   b.  Edit up the request-response-client.cc file and take a look at the Attributes.
   c.  There's really nothing that needs to be done.  We can control the size of the request packet directly with the "PacketSize" attribute.  
   d.  We do that in the script, so edit up ns-3-my-new-app/scratch/request-response.cc
   e.  Search for PacketSize
   f.  Change from 1024 to 10
   g.  Save file.

2. Change server application behavior to return some bigger packet

   a.  Edit up ns-3-my-new-app/src/applications/request-response/request-response-client.cc
   b.  Copy the three lines of the .AddAttribute for the PacketSize to your editors buffer
       .AddAttribute ("PacketSize", "Size of packets generated",
                      UintegerValue (100),
                      MakeUintegerAccessor (&RequestResponseClient::m_size),
                      MakeUintegerChecker<uint32_t> ())
   c.  Edit up ns-3-my-new-app/src/applications/request-response/request-response-server.cc
   d.  Yank the three lines into the GetTypeId method of the server (above the hanging semicolon).
   e.  Change the reference to RequestResponseClient in the new three lines to RequestResponseServer.
   f.  You just added a reference to a variable RequestResponseServer_m_size, so you need to add it to the class.
   g.  Edit up ns-3-my-new-app/src/applications/request-response/request-response-server.h
   h.  Find the declaration of m_port and add a declaration for m_size under it
       uint32_t m_size;
   i.  Edit up ns-3-my-new-app/src/applications/request-response/request-response-server.cc
   j.  Search for RequestResponseServer::HandleRead
   k.  Look for the NS_LOG_LOGIC line and change the string "Echoing Packet" to something like "Responding"
   l.  You're going to need to change the next line of code
       socket->SendTo (packet, 0, from);
       to something reflecting the new m_size attribute.  The easiest way to get there is to steal the code from the client.
   m.  Edit up ns-3-my-new-app/src/applications/request-response/request-response-client.cc
   n.  Find RequestResponseClient::Send
   o.  Copy the following line to your editors buffer:
       Ptr<Packet> p = Create<Packet> (m_size);
   p.  Paste/Yank that line into the request-response-server.cc just uner the NS_LOG_LOGIC you just changed:
   q.  In the following line, change the reference from packet to p.  You should have the following lines of code
       NS_LOG_LOGIC ("Responding");
       Ptr<Packet> p = Create<Packet> (m_size);
       socket->SendTo (p, 0, from);

3. Change script to use new server application behavior

   a.  Edit up ns-3-my-new-app/scratch/request-response.cc
   b.  What you want to do now is to set the new server attribute to some large size (why does it default to 100 now?)
   c.  One way to do this is by command line (see the tutorial for how to do this)
   d.  Another way is in the script.
   e.  Find the ReqeustResponseServer declaration and add similar lines to those setting the packet size in the client app.
       uint32_t responseSize = 1024;
       RequestResponseServerHelper server (port);
       server.SetAttribute ("PacketSize", UintegerValue (responseSize));

3. Build and run your new script with your new application behavior

   a.  ./waf --run scratch/request-response

4. Observe the pcap traces to see what you've done

   a.  > tcpdump -nn -tt -r request-response-0-0.pcap
       reading from file request-response-0-0.pcap, link-type EN10MB (Ethernet)
       2.000000 arp who-has 10.1.1.2 (ff:ff:ff:ff:ff:ff) tell 10.1.1.1
       2.004148 arp reply 10.1.1.2 is-at 00:00:00:00:00:02
       2.004148 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 10
       2.008312 arp who-has 10.1.1.1 (ff:ff:ff:ff:ff:ff) tell 10.1.1.2
       2.008312 arp reply 10.1.1.1 is-at 00:00:00:00:00:01
       2.014100 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024
   b.  Note that a 10 byte request packet goes from 10.1.1.1 (node zero)
   c.  Note that a 1024 byte response packet comes back from 10.1.1.2

5. Go to Disneyland.


Craigdo 18:23, 11 March 2009 (UTC)