rbp_demo.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:10k
源码类别:

通讯编程

开发平台:

Visual C++

  1. #
  2. # rbp_simulation.tcl
  3. # $Id: rbp_demo.tcl,v 1.4 1998/10/21 02:29:47 tomh Exp $
  4. #
  5. # Copyright (c) 1997 University of Southern California.
  6. # All rights reserved.                                            
  7. #                                                                
  8. # Redistribution and use in source and binary forms are permitted
  9. # provided that the above copyright notice and this paragraph are
  10. # duplicated in all such forms and that any documentation, advertising
  11. # materials, and other materials related to such distribution and use
  12. # acknowledge that the software was developed by the University of
  13. # Southern California, Information Sciences Institute.  The name of the
  14. # University may not be used to endorse or promote products derived from
  15. # this software without specific prior written permission.
  16. # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
  17. # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  18. # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19. proc usage {} {
  20. puts stderr {usage: ns rbp_demo.tcl [options]
  21. This simulation is maintained by John Heidemann <johnh@isi.edu>
  22. and was written by John Heidemann and Vikram Visweswaraiah <visweswa@isi.edu>.
  23. It demonstrates rate-based pacing as described in the paper
  24. ``Improving Restart of Idle TCP Connections'' (submitted for publication),
  25. available at <http://www.isi.edu/~johnh/PAPERS/Visweswaraiah97a.html>
  26. when invoked as.
  27. }
  28. exit 1
  29. }
  30. proc default_options {} {
  31. global opts opt_wants_arg
  32. set raw_opt_info {
  33. duration 0
  34. client-count 10
  35. client-bw 10Mb
  36. client-delay 1ms
  37. # client network Ethernet or Myrinet
  38. client-queue-method DropTail
  39. # queue length in packets
  40. client-queue-length 10
  41. client-ack-method TCPSink/DelAck
  42. bottle-bw 800kb
  43. bottle-delay 100ms
  44. bottle-queue-method DropTail
  45. # experiments: 10KB
  46. # here, measured in packets
  47. bottle-queue-length 10
  48. server-bw 10Mb
  49. server-delay 1ms
  50. server-queue-method DropTail
  51. server-queue-length 10
  52. server-tcp-method TCP/Vegas/RBP
  53. server-tcp-slow-start-restart true
  54. server-tcp-window 32
  55. server-tcp-rbp-scale 0.75
  56. # packet size is 1000B
  57. # web page size in 10 pkts
  58. web-page-size 10
  59. experiment-trials 10
  60. # next two are times measured in seconds
  61. trial-jitter 3
  62. inter-trial-pause 20
  63. graph-results 1
  64. graph-join-queueing 1
  65. # For controlling algorithm rate or cwnd
  66. # 1 is Vegas computed rates, 2 is cwnd based alg
  67. rbp-rate-algorithm 1 
  68.                 # time-scale: factor to multiply seconds by to get ns
  69. # scheduler time units
  70. time-scale 1
  71. gen-map 0
  72. debug 0
  73. debug-fire-times 0
  74.     
  75. # Random number seed; default is 0, so ns will give a 
  76. # diff. one on each invocation.
  77. ns-random-seed 0
  78. # Animation options; complete traces are useful
  79. # for nam only, so do those only when a tracefile
  80. # is being used for nam
  81. nam-trace-all 0
  82. # Switch to generate the nam tcl file from here
  83. # itself
  84. nam-generate-cmdfile 0
  85. }
  86. while {$raw_opt_info != ""} {
  87. if {![regexp "^[^n]*n" $raw_opt_info line]} {
  88. break
  89. }
  90. regsub "^[^n]*n" $raw_opt_info {} raw_opt_info
  91. set line [string trim $line]
  92. if {[regexp "^[ t]*#" $line]} {
  93. continue
  94. }
  95. if {$line == ""} {
  96. continue
  97. } elseif [regexp {^([^ ]+)[ ]+([^ ]+)$} $line dummy key value] {
  98. set opts($key) $value
  99. set opt_wants_arg($key) 1
  100. } else {
  101. set opt_wants_arg($key) 0
  102. # die "unknown stuff in raw_opt_infon"
  103. }
  104. }
  105. }
  106. proc process_args {} {
  107. global argc argv opts opt_wants_arg
  108. default_options
  109. for {set i 0} {$i < $argc} {incr i} {
  110. set key [lindex $argv $i]
  111. if {$key == "-?" || $key == "--help" || $key == "-help" || $key == "-h"} {
  112. usage
  113. }
  114. regsub {^-} $key {} key
  115. if {![info exists opt_wants_arg($key)]} {
  116. puts stderr "unknown option $key";
  117. usage
  118. }
  119. if {$opt_wants_arg($key)} {
  120. incr i
  121. set opts($key) [lindex $argv $i]
  122. } else {
  123. set opts($key) [expr !opts($key)]
  124. }
  125. }
  126. }
  127. proc main {} {
  128. global argv
  129. # if {[llength $argv] != 1} {
  130. # usage
  131. # }
  132. process_args
  133. new TestScale
  134. }
  135. proc my-duplex-link {ns n1 n2 bw delay queue_method queue_length} {
  136. $ns duplex-link $n1 $n2 $bw $delay $queue_method
  137. $ns queue-limit $n1 $n2 $queue_length
  138. $ns queue-limit $n2 $n1 $queue_length
  139. }
  140. #
  141. #  clients
  142. #  c1
  143. #  c2    ---- bottle_c ---- bottle_s ---- s
  144. #  ...
  145. #
  146. Class TestScale
  147. TestScale instproc init_network {} {
  148. global opts
  149. # nodes
  150. # build right to left
  151. $self instvar ns_ cs_ bottle_c_ bottle_s_ s_
  152. # build clients
  153. for {set i 0} {$i < $opts(client-count)} {incr i} {
  154. set cs_($i) [$ns_ node]
  155. }
  156. set bottle_c_ [$ns_ node]
  157. set bottle_s_ [$ns_ node]
  158. set s_ [$ns_ node]
  159. # links
  160. my-duplex-link $ns_ $s_ $bottle_s_ $opts(server-bw) $opts(server-delay) $opts(server-queue-method) $opts(server-queue-length)
  161. my-duplex-link $ns_ $bottle_s_ $bottle_c_ $opts(bottle-bw) $opts(bottle-delay) $opts(bottle-queue-method) $opts(bottle-queue-length)
  162. for {set i 0} {$i < $opts(client-count)} {incr i} {
  163. my-duplex-link $ns_ $cs_($i) $bottle_c_ $opts(client-bw) $opts(client-delay) $opts(client-queue-method) $opts(client-queue-length)
  164. }
  165. }
  166. Application/FTP instproc fire {} {
  167. global opts
  168. $self instvar maxpkts_
  169. set maxpkts_ [expr $maxpkts_ + $opts(web-page-size)]
  170. $self produce $maxpkts_
  171. }
  172. TestScale instproc init_connections {} {
  173. global opts
  174. $self instvar ns_ s_  tcp_ ftp_ cs_
  175. for {set i 0} {$i < $opts(client-count)} {incr i} {
  176. set tcp_($i) [$ns_ create-connection $opts(server-tcp-method) $s_ $opts(client-ack-method) $cs_($i) 0]
  177. $tcp_($i) set restart_bugfix_ 1
  178. $tcp_($i) set window_ $opts(server-tcp-window)
  179. if {[regexp "RBP" $opts(server-tcp-method)]} {
  180. $tcp_($i) set rbp_scale_ $opts(server-tcp-rbp-scale)
  181. $tcp_($i) set rbp_rate_algorithm_ $opts(rbp-rate-algorithm)
  182. }
  183. $tcp_($i) set slow_start_restart_ $opts(server-tcp-slow-start-restart)
  184. set ftp_($i) [$tcp_($i) attach-app FTP]
  185. $ftp_($i) set maxpkts_ 0
  186. # $ftp_($i) set experiment_matching_tcp_ $tcp_($i)
  187. # $tcp_($i) set experiment_matching_ftp_ $ftp_($i)
  188. $tcp_($i) set experiment_connection_i_ $i
  189. if {$opts(debug)} {
  190. puts "tcp_($i) $tcp_($i)"
  191. puts "ftp_($i) $ftp_($i)"
  192. }
  193. }
  194. # report on number paced
  195. if [string match {*Vegas/RBP*} $opts(server-tcp-method)] {
  196. Agent/$opts(server-tcp-method) instproc done {} {
  197. $self instvar rbp_segs_actually_paced_ rbp_inter_pace_delay_ experiment_connection_i_ cwnd_ v_rtt_
  198. puts "$experiment_connection_i_: cwnd_=$cwnd_ v_rtt_=$v_rtt_ rbp_segs_actually_paced_=$rbp_segs_actually_paced_ rbp_inter_pace_delay_=$rbp_inter_pace_delay_"
  199. }
  200. }
  201. if [string match {*Reno/RBP*} $opts(server-tcp-method)] {
  202. Agent/$opts(server-tcp-method) instproc done {} {
  203. $self instvar rbp_segs_actually_paced_ rbp_inter_pace_delay_ experiment_connection_i_ cwnd_ rtt_ srtt_
  204. puts "$experiment_connection_i_: cwnd_=$cwnd_ rtt=$rtt_ srtt=$srtt_ rbp_segs_actually_paced_=$rbp_segs_actually_paced_ rbp_inter_pace_delay_=$rbp_inter_pace_delay_"
  205. }
  206. }
  207. }
  208. TestScale instproc schedule_traffic {} {
  209. global opts
  210. $self instvar ns_ s_ tcp_ ftp_ rng_
  211. set base_time [expr 10*$opts(time-scale)]
  212. for {set i 0} {$i < $opts(experiment-trials)} {incr i} {
  213. if {$opts(debug-fire-times)} {
  214. puts "trial $i"
  215. }
  216. # schedule a trial
  217. for {set j 0} {$j < $opts(client-count)} {incr j} {
  218. set j_time [expr ($base_time + [$rng_ uniform 0 $opts(trial-jitter)] - ($opts(trial-jitter))/2) * $opts(time-scale)]
  219. $ns_ at $j_time "$ftp_($j) fire"
  220. if {$opts(debug-fire-times)} {
  221. puts "$ns_ at $j_time $ftp_($j) fire"
  222. }
  223. if { $j == 0 && $opts(debug)} {
  224. puts "$j fires at $j_time"
  225. }
  226. }
  227. incr base_time $opts(inter-trial-pause)
  228. }
  229. # limit duration
  230. if {$opts(duration) == 0} {
  231. set opts(duration) [expr ($opts(experiment-trials)+2)*$opts(inter-trial-pause)*$opts(time-scale)]
  232. }
  233. }
  234. TestScale instproc open_trace { stopTime testName } {
  235. exec rm -f out.tr temp.rands
  236. $self instvar ns_ trace_file_
  237. set trace_file_ [open out.tr w]
  238. $ns_ at $stopTime 
  239. "close $trace_file_ ; $self finish"
  240. return $trace_file_
  241. }
  242. # There seems to be a problem with the foll function, so quit plotting 
  243. # with -a -q, use just -a.
  244. TestScale instproc finish {} {
  245.         global opts
  246. $self instvar trace_file_
  247. if {!$opts(graph-results)} {
  248. exit 0
  249. }
  250. if {$opts(graph-join-queueing)} {
  251. set q "-q"
  252. } else {
  253. set q ""
  254. }
  255. exec raw2xg -a -m $opts(web-page-size) -q < out.tr | xgraph -t "$opts(server-tcp-method)" &
  256. # exec raw2xg -a < out.tr | xgraph -t "$opts(server-tcp-method)" &
  257. exit 0
  258. }
  259. Simulator instproc nodes-to-link {n1 n2} {
  260. $self instvar link_
  261. return $link_([$n1 id]:[$n2 id])
  262. }
  263. TestScale instproc init {} {
  264. global opts
  265. $self instvar ns_ 
  266. set ns_ [new Simulator]
  267.         # Seed random no. generator; ns-random with arg of 0 heuristically
  268.         # chooses a random number that changes on each invocation.
  269. $self instvar rng_
  270. set rng_ [new RNG]
  271. $rng_ seed $opts(ns-random-seed)
  272. $rng_ next-random
  273. $self init_network
  274. $self init_connections
  275. $self schedule_traffic
  276. $self instvar bottle_c_ bottle_s_ s_ cs_
  277. set trace_file [$self open_trace $opts(duration) TestScale]
  278.         if {$opts(nam-trace-all)} {
  279.         # trace-all should have worked, but it didn't, so the 
  280.         # individual trace commands
  281.     
  282.         # Trace from server to server router and vice versa
  283.         $ns_ trace-queue $s_ $bottle_s_ $trace_file
  284.                 $ns_ trace-queue $bottle_s_ $s_ $trace_file
  285.     
  286.         # Trace from the server router to client router and vice 
  287. # versa
  288.         $ns_ trace-queue $bottle_s_ $bottle_c_ $trace_file
  289.         $ns_ trace-queue $bottle_c_ $bottle_s_ $trace_file
  290.         # Trace from client router to each client and vice versa
  291.         for {set i 0} {$i < $opts(client-count)} {incr i} {
  292.         $ns_ trace-queue  $bottle_c_ $cs_($i) $trace_file
  293.         $ns_ trace-queue $cs_($i) $bottle_c_ $trace_file
  294. }
  295. } else {
  296.           $ns_ trace-queue $bottle_s_ $bottle_c_ $trace_file
  297. # note  that we trace after the delay of the bottleneck
  298. $ns_ trace-queue $bottle_s_ $s_ $trace_file
  299. }
  300. if {$opts(gen-map)} {
  301. $ns_ gen-map
  302. }       
  303. $ns_ run
  304. }
  305. main