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

通讯编程

开发平台:

Visual C++

  1. #
  2. # This file contains a preliminary cut at fair-queueing for ns
  3. # as well as a number of stubs for Homework 3 in CS268.
  4. #
  5. # $Header: /cvsroot/nsnam/ns-2/tcl/ex/fq.tcl,v 1.17 2004/08/17 15:26:51 johnh Exp $
  6. #
  7. set ns [new Simulator]
  8. # override built-in link allocator
  9. $ns proc simplex-link { n1 n2 bw delay type } {
  10. $self instvar link_ queueMap_ nullAgent_
  11. $self instvar traceAllFile_
  12. set sid [$n1 id]
  13. set did [$n2 id]
  14. if [info exists queueMap_($type)] {
  15. set type $queueMap_($type)
  16. }
  17. if { $type == "FQ" } {
  18. set link_($sid:$did) [new FQLink $n1 $n2 $bw $delay $nullAgent_]
  19. } else {
  20. set q [new Queue/$type]
  21. $q drop-target $nullAgent_
  22. set link_($sid:$did) [new SimpleLink $n1 $n2 $bw $delay $q]
  23. }
  24. $n1 add-neighbor $n2
  25. #XXX yuck
  26. if { $type == "RED" } {
  27.   set bw [[$link_($sid:$did) set link_] set bandwidth_]
  28. $q set ptc_ [expr $bw / (8. * [$q set mean_pktsize_])]
  29. }
  30.         if [info exists traceAllFile_] {
  31.                 $self trace-queue $n1 $n2 $traceAllFile_
  32.         }
  33. set trace [$self get-ns-traceall]
  34. if {$trace != ""} {
  35. $self trace-queue $n1 $n2 $trace
  36. }
  37. set trace [$self get-nam-traceall]
  38. if {$trace != ""} {
  39. $self namtrace-queue $n1 $n2 $trace
  40. }
  41. }
  42. Class Classifier/Hash/Fid/FQ -superclass Classifier/Hash/Fid
  43. Classifier/Hash/Fid/FQ instproc unknown-flow { src dst fid } {
  44. $self instvar fq_
  45. $fq_ new-flow $src $dst $fid
  46. }
  47. Class FQLink -superclass Link
  48. FQLink instproc init { src dst bw delay nullAgent } {
  49. $self next $src $dst
  50. $self instvar link_ queue_ head_ toNode_ ttl_ classifier_ 
  51. nactive_ drpT_
  52. $self instvar drophead_ ;# idea stolen from CBQ and Kevin
  53. set drpT_ $nullAgent
  54. set nactive_ 0
  55. set queue_ [new Queue/FQ]
  56. set link_ [new DelayLink]
  57. $link_ set bandwidth_ $bw
  58. $link_ set delay_ $delay
  59. set classifier_ [new Classifier/Hash/Fid/FQ 33]
  60. $classifier_ set fq_ $self
  61. $queue_ target $link_
  62. $queue_ drop-target $nullAgent
  63. $link_ target [$toNode_ entry]
  64. set head_ $classifier_
  65. set drophead_ [new Connector]
  66. $drophead_ target [[Simulator instance] set nullAgent_]
  67. # XXX
  68. # put the ttl checker after the delay
  69. # so we don't have to worry about accounting
  70. # for ttl-drops within the trace and/or monitor
  71. # fabric
  72. #
  73. set ttl_ [new TTLChecker]
  74. $ttl_ target [$link_ target]
  75. $link_ target $ttl_
  76. $queue_ set secsPerByte_ [expr 8.0 / [$link_ set bandwidth_]]
  77. }
  78. Queue set limit_ 10
  79. FQLink set queueManagement_ RED
  80. FQLink set queueManagement_ DropTail
  81. FQLink instproc new-flow { src dst fid } {
  82. $self instvar classifier_ nactive_ queue_ link_ drpT_
  83. incr nactive_
  84. set type [$class set queueManagement_]
  85. set q [new Queue/$type]
  86. #XXX yuck
  87. if { $type == "RED" } {
  88.   set bw [$link_ set bandwidth_]
  89. $q set ptc_ [expr $bw / (8. * [$q set mean_pktsize_])]
  90. }
  91. $q drop-target $drpT_
  92. set slot [$classifier_ installNext $q]
  93. $classifier_ set-hash auto $src $dst $fid $slot
  94. $q target $queue_
  95. $queue_ install $fid $q
  96. }
  97. #XXX ask Kannan why this isn't in otcl base class.
  98. FQLink instproc up? { } {
  99. return up
  100. }
  101. #
  102. # should be called after SimpleLink::trace
  103. #
  104. FQLink instproc nam-trace { ns f } {
  105. $self instvar enqT_ deqT_ drpT_ rcvT_ dynT_
  106. if [info exists enqT_] {
  107. $enqT_ namattach $f
  108. if [info exists deqT_] {
  109. $deqT_ namattach $f
  110. }
  111. if [info exists drpT_] {
  112. $drpT_ namattach $f
  113. }
  114. if [info exists rcvT_] {
  115. $rcvT_ namattach $f
  116. }
  117. if [info exists dynT_] {
  118. foreach tr $dynT_ {
  119. $tr namattach $f
  120. }
  121. }
  122. } else {
  123. #XXX 
  124. # we use enqT_ as a flag of whether tracing has been
  125. # initialized
  126. $self trace $ns $f "nam"
  127. }
  128. }
  129. #
  130. # Support for link tracing
  131. # XXX only SimpleLink (and its children) can dump nam config, because Link
  132. # doesn't have bandwidth and delay.
  133. #
  134. FQLink instproc dump-namconfig {} {
  135. # make a duplex link in nam
  136. $self instvar link_ attr_ fromNode_ toNode_
  137. if ![info exists attr_(COLOR)] {
  138. set attr_(COLOR) "black"
  139. }
  140. if ![info exists attr_(ORIENTATION)] {
  141. set attr_(ORIENTATION) ""
  142. }
  143. set ns [Simulator instance]
  144. set bw [$link_ set bandwidth_]
  145. set delay [$link_ set delay_]
  146. $ns puts-nam-config 
  147. "l -t * -s [$fromNode_ id] -d [$toNode_ id] -S UP -r $bw -D $delay -o $attr_(ORIENTATION)"
  148. }
  149. FQLink instproc dump-nam-queueconfig {} {
  150. $self instvar attr_ fromNode_ toNode_
  151. set ns [Simulator instance]
  152. if [info exists attr_(QUEUE_POS)] {
  153. $ns puts-nam-config "q -t * -s [$fromNode_ id] -d [$toNode_ id] -a $attr_(QUEUE_POS)"
  154. } else {
  155. set attr_(QUEUE_POS) ""
  156. }
  157. }
  158. #
  159. # Build trace objects for this link and
  160. # update the object linkage
  161. #
  162. # create nam trace files if op == "nam"
  163. #
  164. FQLink instproc trace { ns f {op ""} } {
  165. $self instvar enqT_ deqT_ drpT_ queue_ link_ head_ fromNode_ toNode_
  166. $self instvar rcvT_ ttl_
  167. $self instvar drophead_ ;# idea stolen from CBQ and Kevin
  168. set enqT_ [$ns create-trace Enque $f $fromNode_ $toNode_ $op]
  169. set deqT_ [$ns create-trace Deque $f $fromNode_ $toNode_ $op]
  170. set drpT_ [$ns create-trace Drop $f $fromNode_ $toNode_ $op]
  171. set rcvT_ [$ns create-trace Recv $f $fromNode_ $toNode_ $op]
  172. $self instvar drpT_ drophead_
  173. set nxt [$drophead_ target]
  174. $drophead_ target $drpT_
  175. $drpT_ target $nxt
  176. $queue_ drop-target $drophead_
  177. # $drpT_ target [$queue_ drop-target]
  178. # $queue_ drop-target $drpT_
  179. $deqT_ target [$queue_ target]
  180. $queue_ target $deqT_
  181. #$enqT_ target $head_
  182. #set head_ $enqT_       -> replaced by the following
  183.         if { [$head_ info class] == "networkinterface" } {
  184.     $enqT_ target [$head_ target]
  185.     $head_ target $enqT_
  186.     # puts "head is i/f"
  187.         } else {
  188.     $enqT_ target $head_
  189.     set head_ $enqT_
  190.     # puts "head is not i/f"
  191. }
  192. # put recv trace after ttl checking, so that only actually 
  193. # received packets are recorded
  194. $rcvT_ target [$ttl_ target]
  195. $ttl_ target $rcvT_
  196. $self instvar dynamics_
  197. if [info exists dynamics_] {
  198. $self trace-dynamics $ns $f $op
  199. }
  200. }
  201. #
  202. # Insert objects that allow us to monitor the queue size
  203. # of this link.  Return the name of the object that
  204. # can be queried to determine the average queue size.
  205. #
  206. FQLink instproc init-monitor ns {
  207. puts stderr "FQLink::init-monitor not implemented"
  208. }
  209. #Queue/RED set thresh_ 3
  210. #Queue/RED set maxthresh_ 8
  211. proc build_topology { ns which } {
  212.         $ns color 1 red
  213.         $ns color 2 white
  214. foreach i "0 1 2 3" {
  215. global n$i
  216. set tmp [$ns node]
  217. set n$i $tmp
  218. }
  219. $ns duplex-link $n0 $n2 5Mb 2ms DropTail
  220. $ns duplex-link $n1 $n2 5Mb 10ms DropTail
  221. $ns duplex-link-op $n0 $n2 orient right-down
  222. $ns duplex-link-op $n1 $n2 orient right-up
  223. if { $which == "FIFO" } {
  224. $ns duplex-link $n2 $n3 1.5Mb 10ms DropTail
  225. } elseif { $which == "RED" } {
  226. $ns duplex-link $n2 $n3 1.5Mb 10ms RED
  227. } else {
  228. $ns duplex-link $n2 $n3 1.5Mb 10ms FQ
  229. }
  230. $ns duplex-link-op $n2 $n3 orient right
  231. $ns duplex-link-op $n2 $n3 queuePos 0.5
  232. }
  233. proc build_tcp { from to startTime } {
  234. global ns
  235. set tcp [new Agent/TCP]
  236. set sink [new Agent/TCPSink]
  237. $ns attach-agent $from $tcp
  238. $ns attach-agent $to $sink
  239. $ns connect $tcp $sink
  240. set ftp [new Application/FTP]
  241. $ftp attach-agent $tcp
  242. $ns at $startTime "$ftp start"
  243. return $tcp
  244. }
  245. proc finish file {
  246. set f [open temp.rands w]
  247. puts $f "TitleText: $file"
  248. puts $f "Device: Postscript"
  249. exec rm -f temp.p temp.d 
  250. exec touch temp.d temp.p
  251. #
  252. # split queue/drop events into two separate files.
  253. # we don't bother checking for the link we're interested in
  254. # since we know only such events are in our trace file
  255. #
  256. exec awk {
  257. {
  258. if (($1 == "+" || $1 == "-" ) && 
  259.     ($5 == "tcp"))
  260. print $2, $8 + ($11 % 90) * 0.01
  261. }
  262. } out.tr > temp.p
  263. exec awk {
  264. {
  265. if ($1 == "d")
  266. print $2, $8 + ($11 % 90) * 0.01
  267. }
  268. } out.tr > temp.d
  269. puts $f "packets
  270. flush $f
  271. exec cat temp.p >@ $f
  272. flush $f
  273. # insert dummy data sets so we get X's for marks in data-set 4
  274. puts $f [format "n"skip-1n0 1nn"skip-2n0 1nn"]
  275. puts $f "drops
  276. flush $f
  277. #
  278. # Repeat the first line twice in the drops file because
  279. # often we have only one drop and xgraph won't print marks
  280. # for data sets with only one point.
  281. #
  282. exec head -n 1 temp.d >@ $f
  283. exec cat temp.d >@ $f
  284. close $f
  285. exec xgraph -bb -tk -nl -m -x time -y packet temp.rands &
  286. # dump the highest seqno sent of each tcp agent
  287. # this gives an idea of throughput
  288. set k 1
  289. while 1 {
  290. global tcp$k
  291. if [info exists tcp$k] {
  292. set tcp [set tcp$k]
  293. puts "tcp$k seqno [$tcp set t_seqno_]"
  294. } else {
  295. break
  296. }
  297. incr k
  298. }
  299. exit 0
  300. }
  301. set f [open out.tr w]
  302. $ns trace-all $f
  303. set nf [open out.nam w]
  304. $ns namtrace-all $nf
  305. build_topology $ns FQ
  306. set tcp1 [build_tcp $n0 $n3 0.1]
  307. $tcp1 set class_ 1
  308. set tcp2 [build_tcp $n1 $n3 0.1]
  309. $tcp2 set class_ 2
  310. $ns at 40.0 "finish Output"
  311. #$ns at 8.0 "xfinish"
  312. proc xfinish {} {
  313. global ns f nf
  314. $ns flush-trace
  315. close $f
  316. close $nf
  317. puts "running nam..."
  318. exec nam out.nam &
  319. exit 0
  320. }
  321. $ns run