📄 many_tcp.tcl
字号:
## many_tcp.tcl# $Id: many_tcp.tcl,v 1.18 2000/09/14 18:19:26 haoboy Exp $## Copyright (c) 1998 University of Southern California.# All rights reserved. # # Redistribution and use in source and binary forms are permitted# provided that the above copyright notice and this paragraph are# duplicated in all such forms and that any documentation, advertising# materials, and other materials related to such distribution and use# acknowledge that the software was developed by the University of# Southern California, Information Sciences Institute. The name of the# University may not be used to endorse or promote products derived from# this software without specific prior written permission.# # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.# proc usage {} { puts stderr {usage: ns rbp_simulation.tcl [options]This simulation demonstrates large numbers of TCP flows.Comments/bugs to John Heidemann <johnh@isi.edu>.Currently this simulation appears to be memory limited for mostpractical purposes. Each active flow consumes ~100KB of memory (veryroughly).Why is a flow so expensive? Primarly because We allocate a separatepair of nodes and links per flow. (I don't know how to do otherwiseand preserve some reasonable statement about the independence ofrandomly selected client RTTs).How can performance be improved?- use multiple concurrent flows per node (should give much bettermemory performance at the cost of node RTT independence)- use session-level simulation techniques (see ``Enabling Large-scalesimulations: selective abstraction approach to the study of multicastprotocols'' by Huang, Estrin, and Heidemann in MASCOTS '98).- improve the efficiency of the underlying representations (there aresome ways to optimize some otcl common cases) (this work is in progress)- use higher level representations of TCP (in progress)Options (specify with -OPTIONNAME OPTIONVALUE):} global raw_opt_info puts stderr $raw_opt_info exit 1}global raw_opt_infoset raw_opt_info { # how long to run the sim? duration 30 # initilization: just start n clients at time 0 # NEEDSWORK: a more realistic ramp-up model # or some kind of autodetection on when we've reached # steady state would be nice. initial-client-count 10 # # BASIC TOPOLOGY: # # (The basic n clients on the left and right going through a # bottleneck.) # # cl_1 cr_1 # ... ---- bottleneck_left ---- bottleneck_right --- ... # cl_n cr_n # # node-number 0 specifies a new pair of nodes # on the left and right for each new client node-number 0 # NEEDSWORK: # The number of agents attached to a node cannot exceed # the port-field length (255 bits). There is currently # no check or warning message for this. # # Currently all data traffic flows left-to-right. # NEEDSWORK: relax this assumption (but Poduri and Nichols # I-D suggests that relaxing it won't change things much). # # # CLIENT TRAFFIC MODEL: # # arrival rate per second (arrival is poisson) client-arrival-rate 1 # Currently clients are either mice or elephants. # NEEDSWORK: should better model http-like traffic patterns. # In particular, netscape's 4-connection model makes # a *big* difference in traffic patterns # and is not currently modeled at all. client-mouse-chance 90 client-mouse-packets 10 client-elephant-packets 100 # For traffic in the reverse direction. client-reverse-chance 0 # Pkt size in bytes. # NEEDSWORK: should check that everything is uniformly # specified (router queues are in packets of 1000B length?). client-pkt-size 576 # # CLIENT NETWORK CONNECTION: # client-bw 56kb # client-server rtt is uniform over this range (currently) # NEEDSWORK: does this need to be modeled more accurately? client-delay random client-delay-range 100ms client-queue-method DropTail # Insure that client routers are never a bottleneck. client-queue-length 100 # # CLIENT/SERVER TCP IMPLEMENTATION: # # NEEDSWORK: should add HTTP model over TCP. source-tcp-method TCP/Reno sink-ack-method TCPSink/DelAck # Set init-win to 1 for initial windows of size 1. # Set init-win to 10 for initial windows of 10 packets. # Set init-win to 0 for initial windows per internet-draft. init-win 1 # # BOTTLENECK LINK MODEL: # bottle-bw 10Mb bottle-delay 4ms bottle-queue-method RED # bottle-queue-length is either in packets or # is "bw-delay-product" which does the currently # expected thing. bottle-queue-length bw-delay-product # # OUTPUT OPTIONS: # graph-results 0 # Set graph-scale to 2 for "rows" for each flow. graph-scale 1 graph-join-queueing 1 gen-map 0 mem-trace 0 print-drop-rate 0 debug 1 title none # set test-suite to write the graph to opts(test-suite-file) test-suite 0 test-suite-file temp.rands # Random number seed; default is 0, so ns will give a # diff. one on each invocation. ns-random-seed 0 # Animation options; complete traces are useful # for nam only, so do those only when a tracefile # is being used for nam # Set trace-filename to "none" for no tracefile. trace-filename out trace-all 0 namtrace-some 0 namtrace-all 0 # Switch to generate the nam tcl file from here # itself nam-generate-cmdfile 0}Class MainMain instproc default_options {} { global opts opt_wants_arg raw_opt_info set cooked_opt_info $raw_opt_info while {$cooked_opt_info != ""} { if {![regexp "^\[^\n\]*\n" $cooked_opt_info line]} { break } regsub "^\[^\n\]*\n" $cooked_opt_info {} cooked_opt_info set line [string trim $line] if {[regexp "^\[ \t\]*#" $line]} { continue } if {$line == ""} { continue } elseif [regexp {^([^ ]+)[ ]+([^ ]+)$} $line dummy key value] { set opts($key) $value set opt_wants_arg($key) 1 } else { set opt_wants_arg($key) 0 # die "unknown stuff in raw_opt_info\n" } }}Main instproc process_args {av} { global opts opt_wants_arg $self default_options for {set i 0} {$i < [llength $av]} {incr i} { set key [lindex $av $i] if {$key == "-?" || $key == "--help" || $key == "-help" || $key == "-h"} { usage } regsub {^-} $key {} key if {![info exists opt_wants_arg($key)]} { puts stderr "unknown option $key"; usage } if {$opt_wants_arg($key)} { incr i set opts($key) [lindex $av $i] } else { set opts($key) [expr !opts($key)] } }}proc my-duplex-link {ns n1 n2 bw delay queue_method queue_length} { global opts $ns duplex-link $n1 $n2 $bw $delay $queue_method $ns queue-limit $n1 $n2 $queue_length $ns queue-limit $n2 $n1 $queue_length}Main instproc init_network {} { global opts fmon # nodes # build right to left $self instvar bottle_l_ bottle_r_ cs_l_ cs_r_ ns_ cs_count_ ns_ clients_started_ clients_finished_ # # Figure supported load. # set expected_load_per_client_in_bps [expr ($opts(client-mouse-chance)/100.0)*$opts(client-mouse-packets)*$opts(client-pkt-size)*8 + (1.0-$opts(client-mouse-chance)/100.0)*$opts(client-elephant-packets)*$opts(client-pkt-size)*8] if {$opts(debug)} { set max_clients_per_second [expr [$ns_ bw_parse $opts(bottle-bw)]/$expected_load_per_client_in_bps] puts [format "maximum clients per second: %.3f" $max_clients_per_second] } # Compute optimal (?) bottleneck queue size # as the bw-delay product. if {$opts(bottle-queue-length) == "bw-delay-product"} { set opts(bottle-queue-length) [expr ([$ns_ bw_parse $opts(bottle-bw)] * ([$ns_ delay_parse $opts(bottle-delay)] + [$ns_ delay_parse $opts(client-delay-range)]) + $opts(client-pkt-size)*8 - 1)/ ($opts(client-pkt-size) * 8)] puts "optimal bw queue size: $opts(bottle-queue-length)" } # Do our own routing with expanded addresses (21 bits nodes). # (Basic routing limits us to 128 nodes == 64 clients). $ns_ rtproto Manual $ns_ set-address-format expanded # set up the bottleneck set bottle_l_ [$ns_ node] set bottle_r_ [$ns_ node] my-duplex-link $ns_ $bottle_l_ $bottle_r_ $opts(bottle-bw) $opts(bottle-delay) $opts(bottle-queue-method) $opts(bottle-queue-length) if {$opts(print-drop-rate)} { set slink [$ns_ link $bottle_l_ $bottle_r_] set fmon [$ns_ makeflowmon Fid] $ns_ attach-fmon $slink $fmon } # Bottlenecks need large routing tables.# [$bottle_l_ set classifier_] resize 511# [$bottle_r_ set classifier_] resize 511 # Default routes to the other. [$bottle_l_ get-module "Manual"] add-route-to-adj-node -default $bottle_r_ [$bottle_r_ get-module "Manual"] add-route-to-adj-node -default $bottle_l_ # Clients are built dynamically. set cs_count_ 0 set clients_started_ 0 set clients_finished_ 0}# create a new pair of end nodesMain instproc create_client_nodes {node} { global opts $self instvar bottle_l_ bottle_r_ cs_l_ cs_r_ sources_ cs_count_ ns_ rng_ set now [$ns_ now] set cs_l_($node) [$ns_ node] set cs_r_($node) [$ns_ node] # Set delay. set delay $opts(client-delay) if {$delay == "random"} { set delay [$rng_ exponential [$ns_ delay_parse $opts(client-delay-range)]] } # Now divide the delay into the two haves and set up the network. set ldelay [$rng_ uniform 0 $delay] set rdelay [expr $delay - $ldelay] my-duplex-link $ns_ $cs_l_($node) $bottle_l_ $opts(client-bw) $ldelay $opts(client-queue-method) $opts(client-queue-length) my-duplex-link $ns_ $cs_r_($node) $bottle_r_ $opts(client-bw) $rdelay $opts(client-queue-method) $opts(client-queue-length) # Add routing in all directions [$cs_l_($node) get-module "Manual"] add-route-to-adj-node -default $bottle_l_ [$cs_r_($node) get-module "Manual"] add-route-to-adj-node -default $bottle_r_ [$bottle_l_ get-module "Manual"] add-route-to-adj-node $cs_l_($node) [$bottle_r_ get-module "Manual"] add-route-to-adj-node $cs_r_($node) if {$opts(debug)} { # puts "t=[format %.3f $now]: node pair $node created" # puts "delay $delay ldelay $ldelay" }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -