80 call. As was seen earlier in the tutorial, the logging system has Doxygen |
80 call. As was seen earlier in the tutorial, the logging system has Doxygen |
81 documentation and now would be a good time to peruse the Logging Module |
81 documentation and now would be a good time to peruse the Logging Module |
82 documentation if you have not done so. |
82 documentation if you have not done so. |
83 |
83 |
84 Now that you have read the documentation in great detail, let's use some of |
84 Now that you have read the documentation in great detail, let's use some of |
85 that knowledge to get some interesting information out of the @code{first.cc} |
85 that knowledge to get some interesting information out of the |
86 example script you have already built. |
86 @code{scratch/myfirst.cc} example script you have already built. |
87 |
87 |
88 @node Enabling Logging |
88 @node Enabling Logging |
89 @subsection Enabling Logging |
89 @subsection Enabling Logging |
90 @cindex NS_LOG |
90 @cindex NS_LOG |
91 Let's use the NS_LOG environment variable to turn on some more logging, but |
91 Let's use the NS_LOG environment variable to turn on some more logging, but |
92 to get our bearings, go ahead and run the script just as you did previously, |
92 to get our bearings, go ahead and run the script just as you did previously, |
93 |
93 |
94 @verbatim |
94 @verbatim |
95 ~/repos/ns-3-dev > ./waf --run scratch/first |
95 ./waf --run scratch/myfirst |
|
96 @end verbtim |
|
97 |
|
98 You should see the now familiar output of the first @command{ns-3} example |
|
99 program |
|
100 |
|
101 @verbatim |
96 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
102 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
97 Compilation finished successfully |
103 Compilation finished successfully |
98 Sent 1024 bytes to 10.1.1.2 |
104 Sent 1024 bytes to 10.1.1.2 |
99 Received 1024 bytes from 10.1.1.1 |
105 Received 1024 bytes from 10.1.1.1 |
100 Received 1024 bytes from 10.1.1.2 |
106 Received 1024 bytes from 10.1.1.2 |
101 ~/repos/ns-3-dev > |
107 @end verbatim |
102 @end verbatim |
108 |
103 |
109 It turns out that the ``Sent'' and ``Received'' messages you see above are |
104 It turns out that the ``Sent'' and ``Received'' messages are actually logging |
110 actually logging messages from the @code{UdpEchoClientApplication} and |
105 messages from the @code{UdpEchoClientApplication} and |
|
106 @code{UdpEchoServerApplication}. We can ask the client application, for |
111 @code{UdpEchoServerApplication}. We can ask the client application, for |
107 example, to print more information by setting its logging level via the |
112 example, to print more information by setting its logging level via the |
108 NS_LOG environment variable. |
113 NS_LOG environment variable. |
109 |
114 |
110 I am going to assume from here on that are using an sh-like shell that uses |
115 I am going to assume from here on that are using an sh-like shell that uses |
111 the``VARIABLE=value'' syntax. If you are using a csh-like shell, then you |
116 the``VARIABLE=value'' syntax. If you are using a csh-like shell, then you |
112 will have to convert my examples to the ``setenv VARIABLE value'' syntax |
117 will have to convert my examples to the ``setenv VARIABLE value'' syntax |
113 required by those shells. |
118 required by those shells. |
114 |
119 |
115 Right now, the UDP echo client application is responding to the following line |
120 Right now, the UDP echo client application is responding to the following line |
116 of code in @code{first.cc}, |
121 of code in @code{scratch/myfirst.cc}, |
117 |
122 |
118 @verbatim |
123 @verbatim |
119 LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); |
124 LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); |
120 @end verbatim |
125 @end verbatim |
121 |
126 |
141 we are going to turn on all of the debugging levels for the application. If |
146 we are going to turn on all of the debugging levels for the application. If |
142 you run the script with NS_LOG set this way, the @command{ns-3} logging |
147 you run the script with NS_LOG set this way, the @command{ns-3} logging |
143 system will pick up the change and you should see the following output: |
148 system will pick up the change and you should see the following output: |
144 |
149 |
145 @verbatim |
150 @verbatim |
146 ~/repos/ns-3-dev > ./waf --run scratch/first |
151 Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' |
147 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
152 Build finished successfully (00:00:00) |
148 Compilation finished successfully |
|
149 UdpEchoClientApplication:UdpEchoClient() |
153 UdpEchoClientApplication:UdpEchoClient() |
150 UdpEchoClientApplication:StartApplication() |
154 UdpEchoClientApplication:StartApplication() |
151 UdpEchoClientApplication:ScheduleTransmit() |
155 UdpEchoClientApplication:ScheduleTransmit() |
152 UdpEchoClientApplication:Send() |
156 UdpEchoClientApplication:Send() |
153 Sent 1024 bytes to 10.1.1.2 |
157 Sent 1024 bytes to 10.1.1.2 |
154 Received 1024 bytes from 10.1.1.1 |
158 Received 1024 bytes from 10.1.1.1 |
155 UdpEchoClientApplication:HandleRead(0x62c640, 0x62cd70) |
159 UdpEchoClientApplication:HandleRead(0x638180, 0x6389b0) |
156 Received 1024 bytes from 10.1.1.2 |
160 Received 1024 bytes from 10.1.1.2 |
157 UdpEchoClientApplication:StopApplication() |
161 UdpEchoClientApplication:StopApplication() |
158 UdpEchoClientApplication:DoDispose() |
162 UdpEchoClientApplication:DoDispose() |
159 UdpEchoClientApplication:~UdpEchoClient() |
163 UdpEchoClientApplication:~UdpEchoClient() |
160 ~/repos/ns-3-dev > |
|
161 @end verbatim |
164 @end verbatim |
162 |
165 |
163 The additional debug information provided by the application is from |
166 The additional debug information provided by the application is from |
164 the NS_LOG_FUNCTION level. This shows every time a function in the application |
167 the NS_LOG_FUNCTION level. This shows every time a function in the application |
165 is called during script execution. Note that there are no requirements in the |
168 is called during script execution. Note that there are no requirements in the |
196 Now, if you run the script you will see that the logging system makes sure |
199 Now, if you run the script you will see that the logging system makes sure |
197 that every message from the given log component is prefixed with the component |
200 that every message from the given log component is prefixed with the component |
198 name. |
201 name. |
199 |
202 |
200 @verbatim |
203 @verbatim |
201 ~/repos/ns-3-dev > ./waf --run scratch/first |
204 Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' |
202 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
205 Build finished successfully (00:00:00) |
203 Compilation finished successfully |
|
204 UdpEchoClientApplication:UdpEchoClient() |
206 UdpEchoClientApplication:UdpEchoClient() |
205 UdpEchoClientApplication:StartApplication() |
207 UdpEchoClientApplication:StartApplication() |
206 UdpEchoClientApplication:ScheduleTransmit() |
208 UdpEchoClientApplication:ScheduleTransmit() |
207 UdpEchoClientApplication:Send() |
209 UdpEchoClientApplication:Send() |
208 UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 |
210 UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 |
209 Received 1024 bytes from 10.1.1.1 |
211 Received 1024 bytes from 10.1.1.1 |
210 UdpEchoClientApplication:HandleRead(0x62c710, 0x62ce40) |
212 UdpEchoClientApplication:HandleRead(0x638180, 0x6389b0) |
211 UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 |
213 UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 |
212 UdpEchoClientApplication:StopApplication() |
214 UdpEchoClientApplication:StopApplication() |
213 UdpEchoClientApplication:DoDispose() |
215 UdpEchoClientApplication:DoDispose() |
214 UdpEchoClientApplication:~UdpEchoClient() |
216 UdpEchoClientApplication:~UdpEchoClient() |
215 ~/repos/ns-3-dev > |
|
216 @end verbatim |
217 @end verbatim |
217 |
218 |
218 You can now see all of the messages coming from the UDP echo client application |
219 You can now see all of the messages coming from the UDP echo client application |
219 are identified as such. The message ``Received 1024 bytes from 10.1.1.2'' is |
220 are identified as such. The message ``Received 1024 bytes from 10.1.1.2'' is |
220 now clearly identified as coming from the echo client application. The |
221 now clearly identified as coming from the echo client application. The |
225 @verbatim |
226 @verbatim |
226 export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func: |
227 export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func: |
227 UdpEchoServerApplication=level_all|prefix_func' |
228 UdpEchoServerApplication=level_all|prefix_func' |
228 @end verbatim |
229 @end verbatim |
229 |
230 |
230 Note that you will need to remove the newline after the @code{:} in the |
231 Warning: You will need to remove the newline after the @code{:} in the |
231 example text above. |
232 example text above which is only there for document formatting purposes. |
232 |
233 |
233 Now, if you run the script you will see all of the log messages from both the |
234 Now, if you run the script you will see all of the log messages from both the |
234 echo client and server applications. You may see that this can be very useful |
235 echo client and server applications. You may see that this can be very useful |
235 in debugging problems. |
236 in debugging problems. |
236 |
237 |
237 @verbatim |
238 @verbatim |
238 ~/repos/ns-3-dev > ./waf --run scratch/first |
239 Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' |
239 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
240 Build finished successfully (00:00:00) |
240 Compilation finished successfully |
|
241 UdpEchoServerApplication:UdpEchoServer() |
241 UdpEchoServerApplication:UdpEchoServer() |
242 UdpEchoClientApplication:UdpEchoClient() |
242 UdpEchoClientApplication:UdpEchoClient() |
243 UdpEchoServerApplication:StartApplication() |
243 UdpEchoServerApplication:StartApplication() |
244 UdpEchoClientApplication:StartApplication() |
244 UdpEchoClientApplication:StartApplication() |
245 UdpEchoClientApplication:ScheduleTransmit() |
245 UdpEchoClientApplication:ScheduleTransmit() |
246 UdpEchoClientApplication:Send() |
246 UdpEchoClientApplication:Send() |
247 UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 |
247 UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 |
248 UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1 |
248 UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1 |
249 UdpEchoServerApplication:HandleRead(): Echoing packet |
249 UdpEchoServerApplication:HandleRead(): Echoing packet |
250 UdpEchoClientApplication:HandleRead(0x62c760, 0x62ce90) |
250 UdpEchoClientApplication:HandleRead(0x638320, 0x638b50) |
251 UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 |
251 UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 |
252 UdpEchoServerApplication:StopApplication() |
252 UdpEchoServerApplication:StopApplication() |
253 UdpEchoClientApplication:StopApplication() |
253 UdpEchoClientApplication:StopApplication() |
254 UdpEchoClientApplication:DoDispose() |
254 UdpEchoClientApplication:DoDispose() |
255 UdpEchoServerApplication:DoDispose() |
255 UdpEchoServerApplication:DoDispose() |
256 UdpEchoClientApplication:~UdpEchoClient() |
256 UdpEchoClientApplication:~UdpEchoClient() |
257 UdpEchoServerApplication:~UdpEchoServer() |
257 UdpEchoServerApplication:~UdpEchoServer() |
258 ~/repos/ns-3-dev > |
|
259 @end verbatim |
258 @end verbatim |
260 |
259 |
261 It is also sometimes useful to be able to see the simulation time at which a |
260 It is also sometimes useful to be able to see the simulation time at which a |
262 log message is generated. You can do this by ORing in the prefix_time bit. |
261 log message is generated. You can do this by ORing in the prefix_time bit. |
263 |
262 |
264 @verbatim |
263 @verbatim |
265 export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time: |
264 export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time: |
266 UdpEchoServerApplication=level_all|prefix_func|prefix_time' |
265 UdpEchoServerApplication=level_all|prefix_func|prefix_time' |
267 @end verbatim |
266 @end verbatim |
268 |
267 |
269 If you run the script now, you should see the following output: |
268 Again, you will have to remove the newline above. If you run the script now, |
270 |
269 you should see the following output: |
271 @verbatim |
270 |
272 ~/repos/ns-3-dev > ./waf --run scratch/first |
271 @verbatim |
273 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
272 Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' |
274 Compilation finished successfully |
273 Build finished successfully (00:00:00) |
275 0s UdpEchoServerApplication:UdpEchoServer() |
274 0s UdpEchoServerApplication:UdpEchoServer() |
276 0s UdpEchoClientApplication:UdpEchoClient() |
275 0s UdpEchoClientApplication:UdpEchoClient() |
277 1s UdpEchoServerApplication:StartApplication() |
276 1s UdpEchoServerApplication:StartApplication() |
278 2s UdpEchoClientApplication:StartApplication() |
277 2s UdpEchoClientApplication:StartApplication() |
279 2s UdpEchoClientApplication:ScheduleTransmit() |
278 2s UdpEchoClientApplication:ScheduleTransmit() |
280 2s UdpEchoClientApplication:Send() |
279 2s UdpEchoClientApplication:Send() |
281 2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 |
280 2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2 |
282 2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1 |
281 2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1 |
283 2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet |
282 2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet |
284 2.00737s UdpEchoClientApplication:HandleRead(0x62c8c0, 0x62d020) |
283 2.00737s UdpEchoClientApplication:HandleRead(0x638490, 0x638cc0) |
285 2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 |
284 2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2 |
286 10s UdpEchoServerApplication:StopApplication() |
285 10s UdpEchoServerApplication:StopApplication() |
287 10s UdpEchoClientApplication:StopApplication() |
286 10s UdpEchoClientApplication:StopApplication() |
288 UdpEchoClientApplication:DoDispose() |
287 UdpEchoClientApplication:DoDispose() |
289 UdpEchoServerApplication:DoDispose() |
288 UdpEchoServerApplication:DoDispose() |
290 UdpEchoClientApplication:~UdpEchoClient() |
289 UdpEchoClientApplication:~UdpEchoClient() |
291 UdpEchoServerApplication:~UdpEchoServer() |
290 UdpEchoServerApplication:~UdpEchoServer() |
292 ~/repos/ns-3-dev > |
|
293 @end verbatim |
291 @end verbatim |
294 |
292 |
295 You can see that the constructor for the UdpEchoServer was called at a |
293 You can see that the constructor for the UdpEchoServer was called at a |
296 simulation time of 0 seconds. This is actually happening before the |
294 simulation time of 0 seconds. This is actually happening before the |
297 simulation starts. The same for the UdpEchoClient constructor. |
295 simulation starts. The same for the UdpEchoClient constructor. |
298 |
296 |
299 Recall that the @code{first.cc} script started the echo server application at |
297 Recall that the @code{scratch/first.cc} script started the echo server |
300 one second into the simulation. You can now see that the |
298 application at one second into the simulation. You can now see that the |
301 @code{StartApplication} method of the server is, in fact, called at one second |
299 @code{StartApplication} method of the server is, in fact, called at one second |
302 (or one billion nanoseconds). You can also see that the echo client |
300 (or one billion nanoseconds). You can also see that the echo client |
303 application is started at a simulation time of two seconds as we requested in |
301 application is started at a simulation time of two seconds as we requested in |
304 the script. |
302 the script. |
305 |
303 |
320 export 'NS_LOG=*=level_all|prefix_func|prefix_time' |
318 export 'NS_LOG=*=level_all|prefix_func|prefix_time' |
321 @end verbatim |
319 @end verbatim |
322 |
320 |
323 The asterisk above is the logging component wildcard. This will turn on all |
321 The asterisk above is the logging component wildcard. This will turn on all |
324 of the logging in all of the components used in the simulation. I won't |
322 of the logging in all of the components used in the simulation. I won't |
325 reproduce the output here (as of this writing it produces 772 lines of output |
323 reproduce the output here (as of this writing it produces 974 lines of output |
326 for the single packet echo) but you can redirect this information into a file |
324 for the single packet echo) but you can redirect this information into a file |
327 and look through it with your favorite editor if you like, |
325 and look through it with your favorite editor if you like, |
328 |
326 |
329 @verbatim |
327 @verbatim |
330 ~/repos/ns-3-dev > ./waf --run scratch/first >& log.out |
328 ./waf --run scratch/myfirst > log.out 2>&1 |
331 @end verbatim |
329 @end verbatim |
332 |
330 |
333 I personally use this quite a bit when I am presented with a problem and I |
331 I personally use this volume of logging quite a bit when I am presented with |
334 have no idea where things are going wrong. I can follow the progress of the |
332 a problem and I have no idea where things are going wrong. I can follow the |
335 code quite easily without having to set breakpoints and step through code |
333 progress of the code quite easily without having to set breakpoints and step |
336 in a debugger. When I have a general idea about what is going wrong, I |
334 through code in a debugger. When I have a general idea about what is going |
337 transition into a debugger for fine-grained examination of the problem. This |
335 wrong, I transition into a debugger for fine-grained examination of the |
338 kind of output can be especially useful when your script does something |
336 problem. This kind of output can be especially useful when your script does |
339 completely unexpected. If you are stepping using a debugger you may miss an |
337 something completely unexpected. If you are stepping using a debugger you |
340 unexpected excursion completely. Logging the excursion makes it quickly |
338 may miss an unexpected excursion completely. Logging the excursion makes it |
341 visible. |
339 quickly visible. |
342 |
340 |
343 @node Adding Logging to your Code |
341 @node Adding Logging to your Code |
344 @subsection Adding Logging to your Code |
342 @subsection Adding Logging to your Code |
345 @cindex NS_LOG |
343 @cindex NS_LOG |
346 You can add new logging to your simulations by making calls to the log |
344 You can add new logging to your simulations by making calls to the log |
347 component via several macros. Let's do so in the @code{first.cc} script we |
345 component via several macros. Let's do so in the @code{myfirst.cc} script we |
348 have in the @code{scratch} directory. |
346 have in the @code{scratch} directory. |
349 |
347 |
350 Recall that we have defined a logging component in that script: |
348 Recall that we have defined a logging component in that script: |
351 |
349 |
352 @verbatim |
350 @verbatim |
355 |
353 |
356 You now know that you can enable all of the logging for this component by |
354 You now know that you can enable all of the logging for this component by |
357 setting the @code{NS_LOG} environment variable to the various levels. Let's |
355 setting the @code{NS_LOG} environment variable to the various levels. Let's |
358 go ahead add some logging to the script. The macro used to add an |
356 go ahead add some logging to the script. The macro used to add an |
359 informational level log message is @code{NS_LOG_INFO}. Go ahead and add one |
357 informational level log message is @code{NS_LOG_INFO}. Go ahead and add one |
360 just before we start creating the nodes that tells you that the script is |
358 (just before we start creating the nodes) that tells you that the script is |
361 ``Creating Topology.'' This is done as in this code snippet, |
359 ``Creating Topology.'' This is done as in this code snippet, |
362 |
360 |
|
361 Open @code{scratch/myfirst.cc} in your favorite editor and add the line, |
|
362 |
363 @verbatim |
363 @verbatim |
364 NS_LOG_INFO ("Creating Topology"); |
364 NS_LOG_INFO ("Creating Topology"); |
|
365 @end verbatim |
|
366 |
|
367 right before the lines, |
|
368 |
|
369 @verbatim |
|
370 NodeContainer nodes; |
|
371 nodes.Create (2); |
365 @end verbatim |
372 @end verbatim |
366 |
373 |
367 Now build the script using waf and clear the @code{NS_LOG} variable to turn |
374 Now build the script using waf and clear the @code{NS_LOG} variable to turn |
368 off the torrent of logging we previously enabled: |
375 off the torrent of logging we previously enabled: |
369 |
376 |
370 @verbatim |
377 @verbatim |
371 ~/repos/ns-3-dev > export NS_LOG= |
378 ./waf |
372 @end verbatim |
379 export NS_LOG= |
373 |
380 @end verbatim |
374 Now, if you run the script, you will not see your new message since its |
381 |
375 associated logging component (@code{FirstScriptExample}) has not been enabled. |
382 Now, if you run the script, |
376 In order to see your message you will have to enable the |
383 |
377 @code{FirstScriptExample} logging component with a level greater than or equal |
384 @verbatim |
378 to @code{NS_LOG_INFO}. If you just want to see this particular level of |
385 ./waf --run scratch/myfirst |
379 logging, you can enable it by, |
386 @end verbatim |
380 |
387 |
381 @verbatim |
388 you will @emph{not} see your new message since its associated logging |
382 ~/repos/ns-3-dev > export NS_LOG=FirstScriptExample=info |
389 component (@code{FirstScriptExample}) has not been enabled. In order to see your |
|
390 message you will have to enable the @code{FirstScriptExample} logging component |
|
391 with a level greater than or equal to @code{NS_LOG_INFO}. If you just want to |
|
392 see this particular level of logging, you can enable it by, |
|
393 |
|
394 @verbatim |
|
395 export NS_LOG=FirstScriptExample=info |
383 @end verbatim |
396 @end verbatim |
384 |
397 |
385 If you now run the script you will see your new ``Creating Topology'' log |
398 If you now run the script you will see your new ``Creating Topology'' log |
386 message, |
399 message, |
387 |
400 |
388 @verbatim |
401 @verbatim |
389 ~/repos/ns-3-dev > ./waf --run scratch/first |
402 Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' |
390 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
403 Build finished successfully (00:00:00) |
391 Compilation finished successfully |
|
392 Creating Topology |
404 Creating Topology |
393 Sent 1024 bytes to 10.1.1.2 |
405 Sent 1024 bytes to 10.1.1.2 |
394 Received 1024 bytes from 10.1.1.1 |
406 Received 1024 bytes from 10.1.1.1 |
395 Received 1024 bytes from 10.1.1.2 |
407 Received 1024 bytes from 10.1.1.2 |
396 ~/repos/ns-3-dev > |
|
397 @end verbatim |
408 @end verbatim |
398 |
409 |
399 @c ======================================================================== |
410 @c ======================================================================== |
400 @c Using Command Line Arguments |
411 @c Using Command Line Arguments |
401 @c ======================================================================== |
412 @c ======================================================================== |
426 } |
437 } |
427 @end verbatim |
438 @end verbatim |
428 |
439 |
429 This simple two line snippet is actually very useful by itself. It opens the |
440 This simple two line snippet is actually very useful by itself. It opens the |
430 door to the @command{ns-3} global variable and attribute systems. Go ahead |
441 door to the @command{ns-3} global variable and attribute systems. Go ahead |
431 and add that two lines of code to the @code{first.cc} script at the start of |
442 and add that two lines of code to the @code{scratch/first.cc} script at the |
432 @code{main}. Go ahead and build the script and run it, but ask the script |
443 start of @code{main}. Go ahead and build the script and run it, but ask the script |
433 for help in the following way, |
444 for help in the following way, |
434 |
445 |
435 @verbatim |
446 @verbatim |
436 ~/repos/ns-3-dev > ./waf --run "scratch/first --PrintHelp" |
447 ./waf --run "scratch/myfirst --PrintHelp" |
437 @end verbatim |
448 @end verbatim |
438 |
449 |
439 This will ask Waf to run the @code{scratch/first} script and pass the command |
450 This will ask Waf to run the @code{scratch/myfirst} script and pass the command |
440 line argument @code{--PrintHelp} to the script. The quotes are required to |
451 line argument @code{--PrintHelp} to the script. The quotes are required to |
441 sort out which program gets which argument. The command line parser will |
452 sort out which program gets which argument. The command line parser will |
442 now see the @code{--PrintHelp} argument and respond with, |
453 now see the @code{--PrintHelp} argument and respond with, |
443 |
454 |
444 @verbatim |
455 @verbatim |
445 ~/repos/ns-3-dev > ./waf --run ``scratch/first --PrintHelp'' |
456 Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' |
446 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
457 Build finished successfully (00:00:00) |
447 Compilation finished successfully |
|
448 --PrintHelp: Print this help message. |
458 --PrintHelp: Print this help message. |
449 --PrintGroups: Print the list of groups. |
459 --PrintGroups: Print the list of groups. |
450 --PrintTypeIds: Print all TypeIds. |
460 --PrintTypeIds: Print all TypeIds. |
451 --PrintGroup=[group]: Print all TypeIds of group. |
461 --PrintGroup=[group]: Print all TypeIds of group. |
452 --PrintAttributes=[typeid]: Print all attributes of typeid. |
462 --PrintAttributes=[typeid]: Print all attributes of typeid. |
453 --PrintGlobals: Print the list of globals. |
463 --PrintGlobals: Print the list of globals. |
454 ~/repos/ns-3-dev > |
|
455 @end verbatim |
464 @end verbatim |
456 |
465 |
457 Let's focus on the @code{--PrintAttributes} option. We have already hinted |
466 Let's focus on the @code{--PrintAttributes} option. We have already hinted |
458 at the @command{ns-3} attribute system while walking through the |
467 at the @command{ns-3} attribute system while walking through the |
459 @code{first.cc} script. We looked at the following lines of code, |
468 @code{first.cc} script. We looked at the following lines of code, |
516 @end verbatim |
525 @end verbatim |
517 |
526 |
518 If you run the script, you should now see the following output, |
527 If you run the script, you should now see the following output, |
519 |
528 |
520 @verbatim |
529 @verbatim |
521 ~/repos/ns-3-dev > ./waf --run scratch/first |
530 Build finished successfully (00:00:00) |
522 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
531 0s UdpEchoServerApplication:UdpEchoServer() |
523 Compilation finished successfully |
532 1s UdpEchoServerApplication:StartApplication() |
524 0ns UdpEchoServerApplication:UdpEchoServer() |
|
525 1000000000ns UdpEchoServerApplication:StartApplication() |
|
526 Sent 1024 bytes to 10.1.1.2 |
533 Sent 1024 bytes to 10.1.1.2 |
527 2257324218ns Received 1024 bytes from 10.1.1.1 |
534 2.25732s Received 1024 bytes from 10.1.1.1 |
528 2257324218ns Echoing packet |
535 2.25732s Echoing packet |
529 Received 1024 bytes from 10.1.1.2 |
536 Received 1024 bytes from 10.1.1.2 |
530 10000000000ns UdpEchoServerApplication:StopApplication() |
537 10s UdpEchoServerApplication:StopApplication() |
531 UdpEchoServerApplication:DoDispose() |
538 UdpEchoServerApplication:DoDispose() |
532 UdpEchoServerApplication:~UdpEchoServer() |
539 UdpEchoServerApplication:~UdpEchoServer() |
533 ~/repos/ns-3-dev > |
|
534 @end verbatim |
540 @end verbatim |
535 |
541 |
536 Recall that the last time we looked at the simulation time at which the packet |
542 Recall that the last time we looked at the simulation time at which the packet |
537 was received by the echo server, it was at 2.0036864 seconds. Now it is |
543 was received by the echo server, it was at 2.00369 seconds. |
538 receiving the packet at about 2.257 seconds. This is because we just dropped |
544 |
|
545 @verbatim |
|
546 2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1 |
|
547 @end verbatim |
|
548 |
|
549 Now it is receiving the packet at 2.25732 seconds. This is because we just dropped |
539 the data rate of the @code{PointToPointNetDevice} down to its default of |
550 the data rate of the @code{PointToPointNetDevice} down to its default of |
540 32768 bits per second from five megabits per second. |
551 32768 bits per second from five megabits per second. |
541 |
552 |
542 If we were to provide a new @code{DataRate} using the command line, we could |
553 If we were to provide a new @code{DataRate} using the command line, we could |
543 speed our simulation up again. We do this in the following way, according to |
554 speed our simulation up again. We do this in the following way, according to |
544 the formula implied by the help item: |
555 the formula implied by the help item: |
545 |
556 |
546 @verbatim |
557 @verbatim |
547 ./waf --run "scratch/first --ns3::PointToPointNetDevice::DataRate=5Mbps" |
558 ./waf --run "scratch/myfirst --ns3::PointToPointNetDevice::DataRate=5Mbps" |
548 @end verbatim |
559 @end verbatim |
549 |
560 |
550 This will set the default value of the @code{DataRate} attribute back to |
561 This will set the default value of the @code{DataRate} attribute back to |
551 five megabits per second. To get the original behavior of the script back, |
562 five megabits per second. Are you surprised by the result? It turns out that |
552 we will have to set the speed-of-light delay of the channel. We can ask the |
563 in order to get the original behavior of the script back, we will have to set |
553 command line system to print out the @code{Attributes} of the channel just |
564 the speed-of-light delay of the channel as well. We can ask the command line |
554 like we did the net device: |
565 system to print out the @code{Attributes} of the channel just like we did for |
555 |
566 the net device: |
556 @verbatim |
567 |
557 ./waf --run "scratch/first --PrintAttributes=ns3::PointToPointChannel" |
568 @verbatim |
|
569 ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointChannel" |
558 @end verbatim |
570 @end verbatim |
559 |
571 |
560 We discover the @code{Delay} attribute of the channel is set in the following |
572 We discover the @code{Delay} attribute of the channel is set in the following |
561 way: |
573 way: |
562 |
574 |
566 @end verbatim |
578 @end verbatim |
567 |
579 |
568 We can then set both of these default values through the command line system, |
580 We can then set both of these default values through the command line system, |
569 |
581 |
570 @verbatim |
582 @verbatim |
571 ./waf --run "scratch/first |
583 ./waf --run "scratch/myfirst |
572 --ns3::PointToPointNetDevice::DataRate=5Mbps |
584 --ns3::PointToPointNetDevice::DataRate=5Mbps |
573 --ns3::PointToPointChannel::Delay=2ms" |
585 --ns3::PointToPointChannel::Delay=2ms" |
574 @end verbatim |
586 @end verbatim |
575 |
587 |
576 in which case we recover the timing we had when we explicitly set the |
588 in which case we recover the timing we had when we explicitly set the |
577 @code{DataRate} and @code{Delay} in the script: |
589 @code{DataRate} and @code{Delay} in the script: |
578 |
590 |
579 @verbatim |
591 @verbatim |
580 Compilation finished successfully |
592 Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' |
581 0ns UdpEchoServerApplication:UdpEchoServer() |
593 Build finished successfully (00:00:00) |
582 1000000000ns UdpEchoServerApplication:StartApplication() |
594 0s UdpEchoServerApplication:UdpEchoServer() |
|
595 1s UdpEchoServerApplication:StartApplication() |
583 Sent 1024 bytes to 10.1.1.2 |
596 Sent 1024 bytes to 10.1.1.2 |
584 2003686400ns Received 1024 bytes from 10.1.1.1 |
597 2.00369s Received 1024 bytes from 10.1.1.1 |
585 2003686400ns Echoing packet |
598 2.00369s Echoing packet |
586 Received 1024 bytes from 10.1.1.2 |
599 Received 1024 bytes from 10.1.1.2 |
587 10000000000ns UdpEchoServerApplication:StopApplication() |
600 10s UdpEchoServerApplication:StopApplication() |
588 UdpEchoServerApplication:DoDispose() |
601 UdpEchoServerApplication:DoDispose() |
589 UdpEchoServerApplication:~UdpEchoServer() |
602 UdpEchoServerApplication:~UdpEchoServer() |
590 @end verbatim |
603 @end verbatim |
591 |
604 |
592 Note that the packet is again received by the server at 2.0036864 seconds. We |
605 Note that the packet is again received by the server at 2.00369 seconds. We |
593 could actually set any of the attributes used in the script in this way. In |
606 could actually set any of the attributes used in the script in this way. In |
594 particular we could set the @code{UdpEchoClient} attribute @code{MaxPackets} |
607 particular we could set the @code{UdpEchoClient} attribute @code{MaxPackets} |
595 to some other value than one. |
608 to some other value than one. |
596 |
609 |
597 How would you go about that? Give it a try. Remember you have to comment |
610 How would you go about that? Give it a try. Remember you have to comment |
644 @end verbatim |
657 @end verbatim |
645 |
658 |
646 Now if you run the script and provide the @code{--PrintHelp} argument, you |
659 Now if you run the script and provide the @code{--PrintHelp} argument, you |
647 should see your new @code{User Argument} listed in the help display. |
660 should see your new @code{User Argument} listed in the help display. |
648 |
661 |
649 @verbatim |
662 Try, |
650 ~/repos/ns-3-dev > ./waf --run "scratch/first --PrintHelp" |
663 |
651 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
664 @verbatim |
652 Compilation finished successfully |
665 ./waf --run "scratch/myfirst --PrintHelp" |
|
666 @end verbatim |
|
667 |
|
668 @verbatim |
|
669 Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' |
|
670 Build finished successfully (00:00:00) |
653 --PrintHelp: Print this help message. |
671 --PrintHelp: Print this help message. |
654 --PrintGroups: Print the list of groups. |
672 --PrintGroups: Print the list of groups. |
655 --PrintTypeIds: Print all TypeIds. |
673 --PrintTypeIds: Print all TypeIds. |
656 --PrintGroup=[group]: Print all TypeIds of group. |
674 --PrintGroup=[group]: Print all TypeIds of group. |
657 --PrintAttributes=[typeid]: Print all attributes of typeid. |
675 --PrintAttributes=[typeid]: Print all attributes of typeid. |
658 --PrintGlobals: Print the list of globals. |
676 --PrintGlobals: Print the list of globals. |
659 User Arguments: |
677 User Arguments: |
660 --nPackets: Number of packets to echo |
678 --nPackets: Number of packets to echo |
661 ~/repos/ns-3-dev > |
|
662 @end verbatim |
679 @end verbatim |
663 |
680 |
664 If you want to specify the number of packets to echo, you can now do so by |
681 If you want to specify the number of packets to echo, you can now do so by |
665 setting the @code{--nPackets} argument in the command line, |
682 setting the @code{--nPackets} argument in the command line, |
666 |
683 |
667 @verbatim |
684 @verbatim |
668 ~/repos/ns-3-dev > ./waf --run "scratch/first --nPackets=2" |
685 ./waf --run "scratch/myfirst --nPackets=2" |
669 Entering directory `/home/craigdo/repos/ns-3-dev/build' |
686 @end verbatim |
670 Compilation finished successfully |
687 |
|
688 You should now see |
|
689 |
|
690 @verbatim |
|
691 Entering directory `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build' |
|
692 Build finished successfully (00:00:00) |
|
693 0s UdpEchoServerApplication:UdpEchoServer() |
|
694 1s UdpEchoServerApplication:StartApplication() |
671 Sent 1024 bytes to 10.1.1.2 |
695 Sent 1024 bytes to 10.1.1.2 |
672 Received 1024 bytes from 10.1.1.1 |
696 2.25732s Received 1024 bytes from 10.1.1.1 |
|
697 2.25732s Echoing packet |
673 Received 1024 bytes from 10.1.1.2 |
698 Received 1024 bytes from 10.1.1.2 |
674 Sent 1024 bytes to 10.1.1.2 |
699 Sent 1024 bytes to 10.1.1.2 |
675 Received 1024 bytes from 10.1.1.1 |
700 3.25732s Received 1024 bytes from 10.1.1.1 |
|
701 3.25732s Echoing packet |
676 Received 1024 bytes from 10.1.1.2 |
702 Received 1024 bytes from 10.1.1.2 |
677 ~/repos/ns-3-dev > |
703 10s UdpEchoServerApplication:StopApplication() |
|
704 UdpEchoServerApplication:DoDispose() |
|
705 UdpEchoServerApplication:~UdpEchoServer() |
678 @end verbatim |
706 @end verbatim |
679 |
707 |
680 You have now echoed two packets. |
708 You have now echoed two packets. |
681 |
709 |
682 You can see that if you are an @command{ns-3} user, you can use the command |
710 You can see that if you are an @command{ns-3} user, you can use the command |
762 @command{ns-2} output, this type of trace is analogous to the @command{out.tr} |
790 @command{ns-2} output, this type of trace is analogous to the @command{out.tr} |
763 generated by many scripts. |
791 generated by many scripts. |
764 |
792 |
765 @cindex tracing packets |
793 @cindex tracing packets |
766 Let's just jump right in and add some ASCII tracing output to our |
794 Let's just jump right in and add some ASCII tracing output to our |
767 @code{first.cc} script. The first thing you need to do is to add the |
795 @code{scratch/myfirst.cc} script. |
768 following code to the script just before the call to @code{Simulator::Run ()}. |
796 |
|
797 The first thing you need to do is to add the following include to the top of |
|
798 the script just after the GNU GPL comment: |
|
799 |
|
800 @verbatim |
|
801 #include <fstream> |
|
802 @end verbatim |
|
803 |
|
804 Then, right before the before the call to @code{Simulator::Run ()}, add the |
|
805 following lines of code. |
769 |
806 |
770 @verbatim |
807 @verbatim |
771 std::ofstream ascii; |
808 std::ofstream ascii; |
772 ascii.open ("first.tr"); |
809 ascii.open ("myfirst.tr"); |
773 PointToPointHelper::EnableAsciiAll (ascii); |
810 PointToPointHelper::EnableAsciiAll (ascii); |
774 @end verbatim |
811 @end verbatim |
775 |
812 |
776 The first two lines are just vanilla C++ code to open a stream that will be |
813 The first two lines are just vanilla C++ code to open a stream that will be |
777 written to a file named ``first.tr.'' See your favorite C++ tutorial if you |
814 written to a file named ``myfirst.tr.'' See your favorite C++ tutorial if you |
778 are unfamiliar with this code. The last line of code in the snippet above |
815 are unfamiliar with this code. The last line of code in the snippet above |
779 tells @command{ns-3} that you want to enable ASCII tracing on all |
816 tells @command{ns-3} that you want to enable ASCII tracing on all |
780 point-to-point devices in your simulation; and you want the (provided) trace |
817 point-to-point devices in your simulation; and you want the (provided) trace |
781 sinks to write out information about packet movement in ASCII format to the |
818 sinks to write out information about packet movement in ASCII format to the |
782 stream provided. For those familiar with @command{ns-2}, the traced events are |
819 stream provided. For those familiar with @command{ns-2}, the traced events are |
783 equivalent to the popular trace points that log "+", "-", "d", and "r" events. |
820 equivalent to the popular trace points that log "+", "-", "d", and "r" events. |
784 |
821 |
785 Since we have used a @code{std::ofstream} object, we also need to include the |
|
786 appropriate header. Add the following line to the script (I typically add it |
|
787 above the ns-3 includes): |
|
788 |
|
789 @verbatim |
|
790 #include <fstream> |
|
791 @end verbatim |
|
792 |
|
793 You can now build the script and run it from the command line: |
822 You can now build the script and run it from the command line: |
794 |
823 |
795 @verbatim |
824 @verbatim |
796 ./waf --run scratch/first |
825 ./waf --run scratch/myfirst |
797 @end verbatim |
826 @end verbatim |
798 |
827 |
799 @cindex first.tr |
828 @cindex myfirst.tr |
800 Just as you have seen previously, you may see some messages from Waf and then |
829 Just as you have seen many times before, you will see some messages from Waf and then |
801 the ``Compilation finished successfully'' with some number of messages from |
830 the ``Build finished successfully'' with some number of messages from |
802 the running program. |
831 the running program. |
803 |
832 |
804 When it ran, the program will have created a file named @code{first.tr}. |
833 When it ran, the program will have created a file named @code{myfirst.tr}. |
805 Because of the way that Waf works, the file is not created in the local |
834 Because of the way that Waf works, the file is not created in the local |
806 directory, it is created at the top-level directory of the repository by |
835 directory, it is created at the top-level directory of the repository by |
807 default. If you want to control where the traces are saved you can use the |
836 default. If you want to control where the traces are saved you can use the |
808 @code{--cwd} option of Waf to specify this. We have not done so, thus we |
837 @code{--cwd} option of Waf to specify this. We have not done so, thus we |
809 need to change into the top level directory of our repo and take a look at |
838 need to change into the top level directory of our repo and take a look at |
810 the ASCII trace file @code{first.tr} in your favorite editor. |
839 the ASCII trace file @code{myfirst.tr} in your favorite editor. |
811 |
840 |
812 @subsubsection Parsing Ascii Traces |
841 @subsubsection Parsing Ascii Traces |
813 @cindex parsing ascii traces |
842 @cindex parsing ascii traces |
814 There's a lot of information there in a pretty dense form, but the first thing |
843 There's a lot of information there in a pretty dense form, but the first thing |
815 to notice is that there are a number of distinct lines in this file. It may |
844 to notice is that there are a number of distinct lines in this file. It may |
935 |
964 |
936 @cindex pcap tracing |
965 @cindex pcap tracing |
937 The code used to enable pcap tracing is a one-liner. |
966 The code used to enable pcap tracing is a one-liner. |
938 |
967 |
939 @verbatim |
968 @verbatim |
940 PointToPointHelper::EnablePcapAll ("first"); |
969 PointToPointHelper::EnablePcapAll ("myfirst"); |
941 @end verbatim |
970 @end verbatim |
942 |
971 |
943 Go ahead and insert this line of code after the ASCII tracing code we just |
972 Go ahead and insert this line of code after the ASCII tracing code we just |
944 added to @code{scratch/first.cc}. Notice that we only passed the string |
973 added to @code{scratch/myfirst.cc}. Notice that we only passed the string |
945 ``first,'' and not ``first.pcap'' or something similar. This is because the |
974 ``myfirst,'' and not ``myfirst.pcap'' or something similar. This is because the |
946 parameter is a prefix, not a complete file name. The helper will actually |
975 parameter is a prefix, not a complete file name. The helper will actually |
947 create a trace file for every point-to-point device in the simulation. The |
976 create a trace file for every point-to-point device in the simulation. The |
948 file names will be built using the prefix, the node number, the device number |
977 file names will be built using the prefix, the node number, the device number |
949 and a ``.pcap'' suffix. |
978 and a ``.pcap'' suffix. |
950 |
979 |
951 In our example script, we will eventually see files named ``first-0-0.pcap'' |
980 In our example script, we will eventually see files named ``myfirst-0-0.pcap'' |
952 and ``first.1-0.pcap'' which are the pcap traces for node 0-device 0 and |
981 and ``myfirst.1-0.pcap'' which are the pcap traces for node 0-device 0 and |
953 node 1-device 0, respectively. |
982 node 1-device 0, respectively. |
954 |
983 |
955 Once you have added the line of code to enable pcap tracing, you can run the |
984 Once you have added the line of code to enable pcap tracing, you can run the |
956 script in the usual way: |
985 script in the usual way: |
957 |
986 |
958 @verbatim |
987 @verbatim |
959 ./waf --run scratch/first |
988 ./waf --run scratch/myfirst |
960 @end verbatim |
989 @end verbatim |
961 |
990 |
962 If you look at the top level directory of your distribution, you should now |
991 If you look at the top level directory of your distribution, you should now |
963 see three log files: @code{first.tr} is the ASCII trace file we have |
992 see three log files: @code{myfirst.tr} is the ASCII trace file we have |
964 previously examined. @code{first-0-0.pcap} and @code{first-1-0.pcap} |
993 previously examined. @code{myfirst-0-0.pcap} and @code{myfirst-1-0.pcap} |
965 are the new pcap files we just generated. |
994 are the new pcap files we just generated. |
966 |
995 |
967 @subsubsection Reading output with tcpdump |
996 @subsubsection Reading output with tcpdump |
968 @cindex tcpdump |
997 @cindex tcpdump |
969 The easiest thing to do at this point will be to use @code{tcpdump} to look |
998 The easiest thing to do at this point will be to use @code{tcpdump} to look |
970 at the @code{pcap} files. Output from dumping both files is shown below: |
999 at the @code{pcap} files. |
971 |
1000 |
972 @verbatim |
1001 @verbatim |
973 ~/repos/ns-3-dev > /usr/sbin/tcpdump -r first-0-0.pcap -nn -tt |
1002 tcpdump -nn -tt -r myfirst-0-0.pcap |
974 reading from file first-0-0.pcap, link-type PPP (PPP) |
1003 reading from file myfirst-0-0.pcap, link-type PPP (PPP) |
975 2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 |
1004 2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 |
976 2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 |
1005 2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 |
977 ~/repos/ns-3-dev > /usr/sbin/tcpdump -r first-1-0.pcap -nn -tt |
1006 |
978 reading from file first-1-0.pcap, link-type PPP (PPP) |
1007 tcpdump -nn -tt -r myfirst-1-0.pcap |
|
1008 reading from file myfirst-1-0.pcap, link-type PPP (PPP) |
979 2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 |
1009 2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024 |
980 2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 |
1010 2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024 |
981 ~/repos/ns-3-dev > |
1011 @end verbatim |
982 @end verbatim |
1012 |
983 |
1013 You can see in the dump of @code{myfirst-0.0.pcap} (the client device) that the |
984 You can see in the dump of ``first-0.0.pcap'' (the client device) that the |
|
985 echo packet is sent at 2 seconds into the simulation. If you look at the |
1014 echo packet is sent at 2 seconds into the simulation. If you look at the |
986 second dump (of ``first-1-0.pcap'') you can see that packet being received |
1015 second dump (@code{first-1-0.pcap}) you can see that packet being received |
987 at 2.257324 seconds. You see the packet being echoed at 2.257324 seconds |
1016 at 2.257324 seconds. You see the packet being echoed back at 2.257324 seconds |
988 in the second dump, and finally, you see the packet being received back at |
1017 in the second dump, and finally, you see the packet being received back at |
989 the client in the first dump at 2.514648 seconds. |
1018 the client in the first dump at 2.514648 seconds. |
990 |
1019 |
991 @subsubsection Reading output with Wireshark |
1020 @subsubsection Reading output with Wireshark |
992 @cindex Wireshark |
1021 @cindex Wireshark |