Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File ns:Avg:can';t使用非数字字符串作为";的操作数+&引用;_File_Tcl_Ns2 - Fatal编程技术网

File ns:Avg:can';t使用非数字字符串作为";的操作数+&引用;

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

这是一段模拟MM1队列服务器的代码(这并不是很重要的事实)。我试图获得每次运行队列中数据包数的平均值。假设我从文件中读取lambda的值,修改它,将新修改的lambda值再次保存到文件中,然后使用lambda的当前值运行模拟:

#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"
}