📄 flows.v2.tcl
字号:
## Set xgraph to 1 to use xgraph, and to 0 to use S.# Set xgraph to 2 to make S-graphs laterset xgraph 1set flowgraphfile fairflow.xgrset timegraphfile fairflow1.xgrset fracgraphfile fairflow2.xgrset friendlygraphfile fairflow3.xgr# drop_interval gets reset in proc flowDumpset drop_interval 2.0set pthresh 100#-------------------------------------------------------------------proc finish file { # # split queue/drop events into two separate files. # we don't bother checking for the link we're interested in # since we know only such events are in our trace file # set awkCode { { if (($1 == "+" || $1 == "-" ) && \ ($5 == "tcp" || $5 == "ack")) print $2, $8 + ($11 % 90) * 0.01 >> "temp.p"; else if ($1 == "d") print $2, $8 + ($11 % 90) * 0.01 >> "temp.d"; } } set f [open temp.rands w] puts $f "TitleText: $file" puts $f "Device: Postscript" exec rm -f temp.p temp.d exec touch temp.d temp.p exec awk $awkCode out.tr puts $f \"packets flush $f exec cat temp.p >@ $f flush $f # insert dummy data sets so we get X's for marks in data-set 4 puts $f [format "\n\"skip-1\n0 1\n\n\"skip-2\n0 1\n\n"] puts $f \"drops flush $f # # Repeat the first line twice in the drops file because # often we have only one drop and xgraph won't print marks # for data sets with only one point. # exec head -1 temp.d >@ $f exec cat temp.d >@ $f close $f exec xgraph -bb -tk -nl -m -x time -y packet temp.rands & exit 0}# plot queue size and average queue sizeproc plotQueue { name } { # # Plot the queue size and average queue size, for RED gateways. # set awkCode { { if ($1 == "Q" && NF>2) { print $2, $3 >> "temp.q"; set end $2 } else if ($1 == "a" && NF>2) print $2, $3 >> "temp.a"; } } set f [open temp.queue w] puts $f "TitleText: $name" puts $f "Device: Postscript" exec rm -f temp.q temp.a exec touch temp.a temp.q exec awk $awkCode out.tr puts $f \"queue flush $f exec cat temp.q >@ $f flush $f puts $f \n\"ave_queue flush $f exec cat temp.a >@ $f ###puts $f \n"thresh ###puts $f 0 [[ns link $r1 $r2] get thresh] ###puts $f $end [[ns link $r1 $r2] get thresh] close $f puts "running xgraph for queue plot..." exec xgraph -bb -tk -x time -y queue temp.queue &}# plot average queue sizeproc plotAveQueue { name } { global xgraph # # Plot the queue size and average queue size, for RED gateways. # set awkCode { { if ($1 == "a" && NF>2) print $2, $3 >> "temp.a"; } } set f [open temp.queue w] puts $f "TitleText: $name" puts $f "Device: Postscript" exec rm -f temp.a exec touch temp.a exec awk $awkCode out.tr puts $f \"queue flush $f puts $f \n\"ave_queue flush $f exec cat temp.a >@ $f close $f puts "running xgraph for queue plot..." if { $xgraph == 1 } { exec xgraph -bb -tk -x time -y queue temp.queue & } if { $xgraph == 0 } { exec csh queue.com temp.queue }}#--------------------------------------------------------------------## Arrange for tcp source stats to be dumped for $tcpSrc every# $interval seconds of simulation time#proc tcpDump { tcpSrc interval } { global ns proc dump { src interval } { ns at [expr [$ns now] + $interval] "dump $src $interval" puts [$ns now]/cwnd=[$src get cwnd]/ssthresh=[$src get ssthresh]/ack=[$src get ack] } $ns at 0.0 "dump $tcpSrc $interval"}proc openTrace { stopTime testName } { global ns r1 k1 set traceFile [open out.tr w] $ns at $stopTime \ "close $traceFile ; finish $testName" set T [$ns trace] $T attach $traceFile return $T}#---------------------------------------------------------------proc flowmonDump { fm dump link stop } { global ns drop_interval if {[$ns now] < $stop} { $dump $link $fm set next [expr [$ns now] + $drop_interval] $ns at $next "flowmonDump $fm $dump $link $stop" }}proc create_flowstats { link dump stoptime } { global ns r1 r2 r1fm flowfile drop_interval flowdesc set r1fm [$ns makeflowmon Fid] set flowdesc [open $flowfile w] $r1fm attach $flowdesc $ns attach-fmon $link $r1fm 1 $ns at $drop_interval "flowmonDump $r1fm $dump $link $stoptime"}proc create_flowstats1 { link dump stoptime } { global ns r1 r2 r1fm flowfile drop_interval flowdesc set r1fm [$ns makeflowmon Fid] set flowdesc [open $flowfile w] $r1fm attach $flowdesc $ns attach-fmon $link $r1fm 1 $ns at $drop_interval "flowmonDump $r1fm $dump $link $stoptime"}proc create_flowstats2 { link dump stoptime } { global ns r1 r2 r1fm flowfile drop_interval flowdesc set r1fm [$ns makeflowmon Fid] set flowdesc [open $flowfile w] $r1fm attach $flowdesc $ns attach-fmon $link $r1fm 0 $ns at $drop_interval "flowmonDump $r1fm $dump $link $stoptime"}#------------------------------------------------------------------## awk code used to produce:# x axis: # arrivals for this flow+category / # total arrivals [bytes]# y axis: # drops for this flow+category / # drops this category [pkts]proc unforcedmakeawk { } { global category if {[string compare $category "unforced"] == 0} { set awkCode { BEGIN { prev=-1; print "\"flow 0"; } { if ($5 != prev) { print " "; print "\"flow " $5; if ($13 > 0 && $14 > 0) { print 100.0 * $9/$13, 100.0 * $10 / $14; } prev = $5; } else if ($13 > 0 && $14 > 0) { print 100.0 * $9 / $13, 100.0 * $10 / $14; } } } return $awkCode } elseif {[string compare $category "forced"] == 0} { set awkCode { BEGIN { prev=-1; print "\"flow 0" } { if ($5 != prev) { print " "; print "\"flow " $5; if ($13 > 0 && ($16-$14) > 0) { print 100.0 * $9/$13, 100.0 * ($18-$10) / ($16-$14); } prev = $5; } else if ($13 > 0 && ($16-$14) > 0) { print 100.0 * $9 / $13, 100.0 * ($18-$10) / ($16-$14); } } } return $awkCode } else { puts stderr "Error: unforcedmakeawk: drop category $category unknown." return {} }}## awk code used to produce:# x axis: # arrivals for this flow+category / # total arrivals [bytes]# y axis: # drops for this flow+category / # drops this category [pkts]# Make sure that N > 2.3 / P^2, for N = # drops this category [pkts],# P = y axis valueproc unforcedmakeawk1 { } { set awkCode { BEGIN { print "\"flow 0" } { if ($5 != prev) { print " "; print "\"flow " $5; drops = 0; flow_drops = 0; arrivals = 0; flow_arrivals = 0; byte_arrivals = 0; flow_byte_arrivals = 0; } drops += $14; flow_drops += $10; arrivals += $12; byte_arrivals += $13; flow_arrivals += $8; flow_byte_arrivals += $9; p = flow_arrivals/arrivals; if (p*p*drops >= 2.3) { print 100.0 * flow_byte_arrivals/byte_arrivals, 100.0 * flow_drops / drops; drops = 0; flow_drops = 0; arrivals = 0; flow_arrivals = 0; byte_arrivals = 0; flow_byte_arrivals = 0; } else { printf "p: %8.2f drops: %d\n", p, drops } prev = $5 } } return $awkCode}#printf "prev=%d,13=%d,17=%d,15=%d\n",prev,$13,$17,$15;## awk code used to produce:# x axis: # arrivals for this flow+category / # total arrivals [bytes]# y axis: # drops for this flow+category / # drops this category [bytes]proc forcedmakeawk { } { global category if {[string compare $category "forced"] == 0} { set awkCode { BEGIN { prev=-1; print "\"flow 0"; } { if ($5 != prev) { print " "; print "\"flow " $5; if ($13 > 0 && ($17-$15) > 0) { print 100.0 * $9/$13, 100.0 * ($19-$11) / ($17-$15); prev = $5; } } else if ($13 > 0 && ($17-$15) > 0) { print 100.0 * $9 / $13, 100.0 * ($19-$11) / ($17-$15); } } } return $awkCode } elseif {[string compare $category "unforced"] == 0} { set awkCode { BEGIN { prev=-1; print "\"flow 0"; } { if ($5 != prev) { print " "; print "\"flow " $5; if ($13 > 0 && $15 > 0) { print 100.0 * $9/$13, 100.0 * $11 / $15; prev = $5; } } else if ($13 > 0 && $15 > 0) { print 100.0 * $9 / $13, 100.0 * $11 / $15; } } } return $awkCode } else { puts stderr "Error: forcedmakeawk: drop category $category unknown." return {} }}## awk code used to produce:# x axis: # arrivals for this flow+category / # total arrivals [bytes]# y axis: # drops for this flow / # drops [pkts and bytes combined]proc allmakeawk_old { } { set awkCode { BEGIN { prev=-1; frac_bytes=0; frac_packets=0; frac_arrivals=0; cat0=0; cat1=0} { if ($5 != prev) { print " "; print "\"flow "$5; prev = $5 } if (cat1 + cat0 > 0) { if (frac_packets + frac_bytes > 0) { cat1_part = frac_packets * cat1 / ( cat1 + cat0 ) cat0_part = frac_bytes * cat0 / ( cat1 + cat0 ) print 100.0 * frac_arrivals, 100.0 * ( cat1_part + cat0_part ) } frac_bytes = 0; frac_packets = 0; frac_arrivals = 0; cat1 = 0; cat0 = 0; prevtime = $1 } if ($14 > 0) { frac_packets = $10/$14; } else { frac_packets = 0; } if (($17-$15) > 0) { frac_bytes = ($19-$11)/($17-$15); } else { frac_bytes = 0; } if ($13 > 0) { frac_arrivals = $9/$13; } else { frac_arrivals = 0; } cat0 = $16-$14; cat1 = $14; } END { if (frac_packets + frac_bytes > 0 && cat1 + cat0 > 0) { cat1_part = frac_packets * cat1 / ( cat1 + cat0 ) cat0_part = frac_bytes * cat0 / ( cat1 + cat0 ) print 100.0 * frac_arrivals, 100.0 * ( cat1_part + cat0_part ) } } } return $awkCode}## awk code used to produce:# x axis: # arrivals for this flow+category / # total arrivals [bytes]# y axis: # drops for this flow / # drops [pkts and bytes combined]proc allmakeawk { } { set awkCode { BEGIN {prev=-1; tot_bytes=0; tot_packets=0; forced_total=0; unforced_total=0} { if ($5 != prev) { print " "; print "\"flow ",$5; prev = $5 } tot_bytes = $19-$11; forced_total= $16-$14; tot_packets = $10; tot_arrivals = $9; unforced_total = $14; if (unforced_total + forced_total > 0) { if ($14 > 0) { frac_packets = tot_packets/$14; } else { frac_packets = 0;} if ($17-$15 > 0) { frac_bytes = tot_bytes/($17-$15); } else {frac_bytes = 0;} if ($13 > 0) { frac_arrivals = tot_arrivals/$13; } else {frac_arrivals = 0;} if (frac_packets + frac_bytes > 0) { unforced_total_part = frac_packets * unforced_total / ( unforced_total + forced_total) forced_total_part = frac_bytes * forced_total / ( unforced_total + forced_total) print 100.0 * frac_arrivals, 100.0 * ( unforced_total_part +forced_total_part) } } } } return $awkCode}#--------------------------------------------------------------proc create_flow_graph { graphtitle graphfile awkprocedure } { global flowfile exec rm -f $graphfile set outdesc [open $graphfile w] #
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -