我使用的是Ns2和tcl脚本。在下面的代码中,我想使用全局变量rate12,它在表达式中的值为2Mb
if { $queuesize>16 } {
set RL [expr $Rc * $fdec * $hf]
set rate12 [expr $rate12 * $RL]
puts $rate12
}
从proc记录中找到。但它显示以下错误:
ns: record _o104 file5: invalid bareword "Mb" in expression "4_@_Mb * 0.40000000000000002"; should be "$Mb" or "{Mb}" or "Mb(...)" or ... (parsing expression "4Mb * 0.40000000000000...") invoked from within "expr $rate12 * $RL" (procedure "record" line 26) invoked from within "record _o104 file5"
我该如何修复错误?
整个代码是:
#Create a simulator object
set ns [new Simulator]
global rate02
global rate12
global rate23
global rate32
#Define different colors for data flows (for NAM)
$ns color 1 Blue
$ns color 2 Red
$ns color 3 Green
#Open the NAM trace file
set nf [open out.nam w]
$ns namtrace-all $nf
# constants
global Rc
global Fdec
global hf
#Define a 'finish' procedure
proc finish {} {
global ns nf
$ns flush-trace
#Close the NAM trace file
close $nf
#Execute NAM on the trace file
exec nam out.nam &
exit 0
}
#Create four nodes
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
set rate02 2Mb
set rate12 4Mb
set rate23 2Mb
set rate32 0.1Mb
#Create links between the nodes
$ns duplex-link $n0 $n2 $rate02 10ms RED
$ns duplex-link $n1 $n2 $rate12 10ms DropTail
$ns duplex-link $n2 $n3 $rate23 20ms DropTail
$ns duplex-link $n3 $n2 $rate32 10ms DropTail
#Set Queue Size of link (n2-n3) to 10
$ns queue-limit $n2 $n3 16
#Give node position (for NAM)
$ns duplex-link-op $n0 $n2 orient right-down
$ns duplex-link-op $n1 $n2 orient right-up
$ns duplex-link-op $n2 $n3 orient right
#Monitor the queue for link (n2-n3). (for NAM)
$ns duplex-link-op $n2 $n3 queuePos 0.5
#creat file record infomation at queues
set queue03 [$ns monitor-queue $n2 $n3 [open qsize03.tr w] 0.05]
set qsize03 [open qsize03.tr w]
proc record {queue qsize} {
global ns
#set ns [Simulator instance]
set time 0.1
set now [$ns now]
#print current qsize in $queuesize
$queue instvar parrivals_ pdepartures_ bdros_ bdepartures_ pdrops_
#set queuesize [expr $parrivals_ - $pdepartures_ - $pdrops_]
set queuesize $parrivals_
puts $queuesize
puts $qsize "$now [expr $parrivals_ - $pdepartures_ - $pdrops_]"
#puts "$now [expr $parrivals_ - $pdepartures_ - $pdrops_]"
set $bdepartures_ 0
set Rc 2
set fdec 0.4
set hf 0.5
global rate12
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
if { $queuesize>16 } {
set RL [expr $Rc * $fdec * $hf]
set rate12 [expr $rate12 * $RL]
puts $rate12
$ns duplex-link $n0 $n2 0.8Mb 10ms RED
} elseif { $queuesize==20 } {
puts "full"
} else {
puts "under"
}
$ns at [expr $now + $time] "record $queue $qsize"
}
#Setup a TCP connection
set tcp1 [new Agent/TCP]
$tcp1 set class_ 2
$ns attach-agent $n0 $tcp1
set sink [new Agent/TCPSink]
$ns attach-agent $n3 $sink
$ns connect $tcp1 $sink
$tcp1 set fid_ 1
#########################################
#Setup a TCP connection
set tcp3 [new Agent/TCP]
$tcp3 set class_ 2
$ns attach-agent $n3 $tcp3
set sink2 [new Agent/TCPSink]
$ns attach-agent $n1 $sink2
$ns connect $tcp3 $sink2
$tcp3 set fid_ 3
#Setup a FTP over TCP connection
set ftp3 [new Application/FTP]
$ftp3 attach-agent $tcp3
$ftp3 set type_ FTP
############################################
#Setup a FTP over TCP connection
set ftp1 [new Application/FTP]
$ftp1 attach-agent $tcp1
$ftp1 set type_ FTP
#Setup a TCP connection
set tcp2 [new Agent/TCP]
$tcp2 set class_ 2
$ns attach-agent $n1 $tcp2
set sink [new Agent/TCPSink]
$ns attach-agent $n3 $sink
$ns connect $tcp2 $sink
$tcp2 set fid_ 2
#Setup a FTP over TCP connection
set ftp2 [new Application/FTP]
$ftp2 attach-agent $tcp2
$ftp2 set type_ FTP
#Schedule events for the CBR and FTP agents
$ns at 0.1 "$ftp2 start"
$ns at 0.5 "record $queue03 $qsize03"
$ns at 1.0 "$ftp1 start"
$ns at 1.0 "$ftp3 start"
$ns at 4.0 "$ftp2 stop"
$ns at 4.5 "$ftp1 stop"
$ns at 4.5 "$ftp3 stop"
#Detach tcp and sink agents (not really necessary)
$ns at 4.5 "$ns detach-agent $n0 $tcp1 ; $ns detach-agent $n3 $sink"
$ns at 4.5 "$ns detach-agent $n1 $tcp2 ; $ns detach-agent $n3 $sink"
#Call the finish procedure after 5 seconds of simulation time
$ns at 5.0 "finish"
$ns run
答案 0 :(得分:4)
Tcl的expr
命令不适用于具有类似Mb的单位的值。
因此它尝试解释值$rate12
,即4Mb,但这不是有效的数字文字,因此您得到错误。结合您不支持表达的事实,例如你写道:
set rate12 [expr $rate12 * $RL]
而不是
set rate12 [expr {$rate12 * $RL}]
你得到expr的双重评估,这会产生误导性的错误信息(并且可能会慢很多)。
要解决此问题,您需要对没有单位的值进行计算,或者使用包含单位的小proc来执行此操作。
答案 1 :(得分:1)
关键字global
仅在proc
的范围内有意义。要访问rate12
,请在proc record
的开头添加以下行:
global rate12
那应该解决你的问题。
我的不好,我没有在proc中间看到global
命令。问题是你刚开始的时候:
set rate12 4Mb
稍后,在proc record
:
set rate12 [expr $rate12 * $RL]
根据Tcl,4Mb
不是数字。我建议以下修复:
set rate12 4
或者,更具描述性:
set rateInMb12 4