File ns:Avg:can';t使用非数字字符串作为";的操作数+&引用;
这是一段模拟MM1队列服务器的代码(这并不是很重要的事实)。我试图获得每次运行队列中数据包数的平均值。假设我从文件中读取lambda的值,修改它,将新修改的lambda值再次保存到文件中,然后使用lambda的当前值运行模拟:File ns:Avg:can';t使用非数字字符串作为";的操作数+&引用;,file,tcl,ns2,File,Tcl,Ns2,这是一段模拟MM1队列服务器的代码(这并不是很重要的事实)。我试图获得每次运行队列中数据包数的平均值。假设我从文件中读取lambda的值,修改它,将新修改的lambda值再次保存到文件中,然后使用lambda的当前值运行模拟: #Create a simulator object set ns [new Simulator] global ns tracefile namf Qsize Qbw Qlost Qmon Avgvals InterArrivalTime lambda pro
#Create a simulator object
set ns [new Simulator]
global ns tracefile namf Qsize Qbw Qlost Qmon Avgvals InterArrivalTime lambda
proc readfile {filename} {
set f [open $filename]
set data [read $f]
close $f
return $data
}
proc writefile {filename data} {
set f [open $filename w]
puts -nonewline $f $data
close $f
}
#Define different colors for data flow (for NAM)
$ns color 1 Blue
#Open the NAM trace file
set namf [open QMM1.nam w]
$ns namtrace-all $namf
set Qsize [open Qsize.tr w]
set Qbw [open Qbw.tr w]
set Qlost [open Qlost.tr w]
set Avgvals [open Avgvals.tr a+]
set tracefile [open out.tr w]
$ns trace-all $tracefile
#set lambda and Mu
set mu 1100.0
catch {set lambda [readfile LamdaValue.tr]}
set lambda [expr {$lambda + 100.0}]
writefile LamdaValue.tr $lambda
#Create the Node to generate the traffic Queue and Server
set n1 [$ns node]
set n2 [$ns node]
# Since packet sizes will be rounded to an integer
# number of bytes, we should have large packets and
# to have small rounding errors, and so we take large bandwidth
#Create link between the two nodes
set link [$ns simplex-link $n1 $n2 100kb 0ms DropTail]
#Monitor the queue for link (n1-n2) for nam
$ns simplex-link-op $n1 $n2 queuePos 0.5
#set up a large Queue capacity (n1-n2)
$ns queue-limit $n1 $n2 100000
# generate random interarrival times and packet sizes
#Set arrivals to be exponential
set InterArrivalTime [new RandomVariable/Exponential]
#Avg=1/lambda
#$InterArrivalTime set avg_ [expr 1/$lambda]
set pktSize [new RandomVariable/Exponential]
$pktSize set avg_ [expr 100000.0/(8*$mu)]
#Set src to use UDP
set src [new Agent/UDP]
$src set fid_ 1
$ns attach-agent $n1 $src
# queue monitoring, write statistics to queueStat
set Qmon [$ns monitor-queue $n1 $n2 [open queueStat.out w] 0.1]
$link queue-sample-timeout
proc record {} {
global ns Qmon Qsize Qbw Qlost n1 n2 Avgvals lambda
set time 0.05
set now [$ns now]
# print in the file $Qsize the current queue size
# print in the file $Qbw the current used bandwidth
# print in the file $Qlost the loss rate
$Qmon instvar parrivals_ pdepartures_ bdrops_ bdepartures_ pdrops_
puts $Qsize "[expr $parrivals_-$pdepartures_-$pdrops_]"
puts $Qbw "$now [expr $bdepartures_*8/1024/$time]"
set bdepartures_ 0
puts $Qlost "$now [expr $pdrops_/$time]"
$ns at [expr $now+$time] "record"
}
proc finish {} {
global ns tracefile namf Qsize Qbw Qlost Qmon
$ns flush-trace
#Close the NAM trace file
close $namf
close $Qsize
close $Qbw
close $Qlost
close $tracefile
#Execute NAM on the trace file
#exec ./nam QMM1.nam &
exit 0
}
proc sendpacket {} {
global ns src InterArrivalTime pktSize
set time [$ns now]
$ns at [expr $time + [$InterArrivalTime value]] "sendpacket"
set bytes [expr round ([$pktSize value])]
$src send $bytes
}
proc Avg {} {
global ns Qmon Qsize Qbw Qlost n1 n2 Avgvals lambda
set sum 0.0
set c 1
set fid [open Qsize.tr r]
set txt [read $fid]
close $fid
foreach {x} $txt {
set sum [expr {$sum + $x}]
incr c 1
}
set avg [expr $sum/$c]
puts $Avgvals "$lambda $avg"
}
set sink [new Agent/Null]
$ns attach-agent $n2 $sink
$ns connect $src $sink
proc repeatSim {} {
global lambda
if {$lambda < 1002} {
exec ./ns QMM1.tcl &
}
}
#Avg=1/lambda
$InterArrivalTime set avg_ [expr 1/$lambda]
puts "Lambda = $lambda"
puts "Mu = $mu"
$ns at 0.0 "record"
$ns at 0.0001 "sendpacket"
$ns at 1000.0 "Avg"
$ns at 1000.0 "repeatSim"
#Run the simulation
$ns run
我在代码中尝试了几次操作,但错误仍然以相同的方式显示。
您能告诉我问题出在哪里吗?如何调试代码的演练
让我们更仔细地查看该错误消息
ns: Avg: can't use non-numeric string as operand of "+"
while executing
"expr {$sum + $x}"
(procedure "Avg" line 12)
invoked from within
"Avg"
好的,出现问题的那一行在foreach
中,它被用来将$txt
(即从文件中读取)的字作为浮点数添加(因为sum
被初始化为0.0
)。好吧,既然sum
将继续保持一个浮点数,只要所有要添加的值都是数字,那么我们就必须有一个问题,即文件中的一个字不是数字。它不能是其他任何东西,因为表达式本身在大括号中,保证了在Tcl级别的可靠解释。(expr$sum/$c没有那么好,但在Tcl 8.5和8.6中,我们使用定制的高可靠性浮点到字符串转换器,而不是标准c库中有些不稳定的转换器。)
我们无法从所提供的信息中判断违规价值是什么;错误跟踪没有记录它(它不能保存所有内容,否则会太难处理),并且您没有提供失败的示例。如果要调试,可以尝试将代码更改为:
proc Avg {} {
global ns Qmon Qsize Qbw Qlost n1 n2 Avgvals lambda
set sum 0.0
set c 1
set fid [open Qsize.tr r]
set txt [read $fid]
close $fid
foreach {x} $txt {
if {[catch {
set sum [expr {$sum + $x}]
incr c 1
}] {
puts "The value at index #$c ('$x') is not numeric"
}
}
set avg [expr $sum/$c]
puts $Avgvals "$lambda $avg"
}
如果问题是您正在读取的文件中有额外的元语法,那么您需要在对值求和之前处理它
你的代码也有一个bug:“平均值”会有点低,因为
c
最后太大了。我不是ns2
方面的专家。但是,查看您收到的错误消息,似乎从文件中读取的x
的值可能是字母或特殊字符,而不是数值。您已将sum
初始化为0.0。所以,奇怪的人指出了x
的问题。你能检查一下吗?你真的需要发布所有的代码来告诉我们这个问题吗?请编辑您的问题并删除任何不直接影响问题的内容。
ns: Avg: can't use non-numeric string as operand of "+"
while executing
"expr {$sum + $x}"
(procedure "Avg" line 12)
invoked from within
"Avg"
proc Avg {} {
global ns Qmon Qsize Qbw Qlost n1 n2 Avgvals lambda
set sum 0.0
set c 1
set fid [open Qsize.tr r]
set txt [read $fid]
close $fid
foreach {x} $txt {
set sum [expr {$sum + $x}]
incr c 1
}
set avg [expr $sum/$c]
puts $Avgvals "$lambda $avg"
}
proc Avg {} {
global ns Qmon Qsize Qbw Qlost n1 n2 Avgvals lambda
set sum 0.0
set c 1
set fid [open Qsize.tr r]
set txt [read $fid]
close $fid
foreach {x} $txt {
if {[catch {
set sum [expr {$sum + $x}]
incr c 1
}] {
puts "The value at index #$c ('$x') is not numeric"
}
}
set avg [expr $sum/$c]
puts $Avgvals "$lambda $avg"
}