如何修复 TCL ns2 中的错误

How to fix Errors in TCL ns2

我对 NS2 的使用非常天真,并试图在 NS2 和 TCP 中通过 UDP 实现 CBR。

当我尝试编译它时,它给了我这个错误:

ns: _o28 start: 
    (_o28 cmd line 1)
    invoked from within
"_o28 cmd start"
    invoked from within
"catch "$self cmd $args" ret"



   invoked from within
"if [catch "$self cmd $args" ret] {
set cls [$self info class]
global errorInfo
set savedInfo $errorInfo
error "error when calling class $cls: $args" $..."
    (procedure "_o28" line 2)
    (SplitObject unknown line 2)
    invoked from within
"_o28 start"

这是我的代码..我试图通过查看互联网来修复它,但我没有得到任何有用的东西

        # Création du simulateur
set ns [new Simulator]
# Création des fichiers de traces NS-2
set nf [open out.nam w]
$ns namtrace-all $nf
$ns trace-all [open out1.tr w]

# Création des noeuds
set N1 [$ns node]
$N1 label "source cbr"
set N2 [$ns node]
$N2 label "source tcp"
set R1 [$ns node]
set R2 [$ns node]
set N3 [$ns node]
$N3 label "destination tcp"
set N4 [$ns node]
$N4 label "destination cbr"


#Setup a TCP connection
set tcp [new Agent/TCP]
$tcp set class_ 2
$ns attach-agent $N2 $tcp
set sink [new Agent/TCPSink]
$ns attach-agent $N3 $sink
$ns connect $tcp $sink
$tcp set fid_ 1

#Setup a FTP over TCP connection
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ftp set type_ FTP


#Setup a UDP connection
set udp [new Agent/UDP]
$ns attach-agent $N1 $udp
set null [new Agent/Null]
$ns attach-agent $N4 $null
$ns connect $udp $null
$udp set fid_ 2

#Setup a CBR over UDP connection
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $udp
$cbr set type_ CBR
$cbr set packet_size_ 1000
$cbr set rate_ 1mb
$cbr set random_ false


# Création des liens, tous en 1Mbps/10ms de TR/file d'attente DropTail
$ns duplex-link $N1 $R1 10Mb 15ms DropTail
$ns duplex-link $N2 $R1 10Mb 15ms DropTail
$ns duplex-link $R1 $R2 5Mb  40ms DropTail
$ns duplex-link $R2 $N3 12Mb 15ms DropTail
$ns duplex-link $R2 $N4 6Mb 15ms DropTail

    #capacité file d'attente R1-R2
    $ns queue-limit $R1 $R2 50



# gestion du layout de la topologie

$ns duplex-link-op $R2 $N4 orient right-down
$ns duplex-link-op $R2 $N3 orient right-up
$ns duplex-link-op $R1 $R2 orient right
$ns duplex-link-op $N1 $R1 orient left-up
$ns duplex-link-op $N2 $R1 orient left-down

#$ns duplex-link-op $R1 $R2 queuePos 0.5 # voir l’état de la file





# Création d'un agent vide, destiné à recevoir les paquets implantés dans n3
set null0 [new Agent/Null]
$ns attach-agent $N3 $null0

# Création d'un agent vide, destiné à recevoir les paquets implantés dans n3
set tcpsink [new Agent/TCPSink]
$ns attach-agent $N4 $tcpsink

# Le traffic issu des agents udp0 et udp1 est envoyé vers null0
$ns connect $udp $null0
$ns connect $tcp $tcpsink




# Scénario de début et de fin de génération des paquets par cbr0
$ns at 0.0 "$cbr start"
$ns at 0.2 "$tcp start"
$ns at 4 "$tcp stop"

$ns at 5.0 "$cbr stop"
# Définition de classes pour la coloration



# Coloration des classes : bleu pour udp (classe 1) et rouge pour tcp (classe 2)
$ns color 1 Blue
$ns color 2 Red


# Procédure de fin de simulation, qui écrit les données dans le fichier
# et lance NAM pour la visualisation
proc fin {} {
global ns nf
$ns flush-trace
close $nf
exec nam out.nam &
exit 0
} 
# La simulation va durer 15 secondes et appelle la procédure finish
$ns at 6.0 "fin"
# Début de la simulation
$ns run

NS2 建立在一个用 Tcl 编写的称为 OTcl 的对象系统之上。现在这是一个相当古老的系统; Tcl 中的其他人(完全使用对象系统的人)使用其他东西。原因之一是调试 OTcl 程序比大多数 Tcl 程序更笨拙。

但这并不能解决这里的问题!如果我们查看该堆栈跟踪,我们可以从启动它的调用中选择返回方式:

"_o28 start"

到出现错误的地方:

    (_o28 cmd line 1)

唉,中间的一切 都只是 OTcl 机器。这对我来说很讨厌,因为我注意到其中有一些不好的做法,但这不应该让你担心:它不在 你的 代码中,而是在你正在使用的库中.

不幸的是,不管是什么原因造成的错误都没有给我们错误信息!这太可怕了。但是,我们可以从方法名称中猜测是调用它的这些行之一(延迟到模拟器引擎到达该时间戳):

$ns at 0.0 "$cbr start"
$ns at 0.2 "$tcp start"

这是哪个? Application/Traffic/CBR class 或 Agent/TCP class 的 start 方法?我真的不知道!堆栈跟踪巧妙地忽略了这一点。方法定义未显示在您的代码示例中,实际上可能在 C 或 C++ 中。我们根本没有这些信息。我们确实知道它看起来像是来自该启动方法主体的第一行,但仅此而已。

由于您使用的是全局变量,您可以(可能)更改这两个回调设置行来执行此操作:

$ns at 0.0 {$cbr start}
$ns at 0.2 {$tcp start}

这会将变量的替换推迟到调用时间,并且 可能 使您的堆栈跟踪信息足以计算出哪个 class 的 start方法有问题。它不会解决问题,但它可能会让您更轻松地找到它。


总的来说,您的代码似乎是合理的 Tcl。它使用的是 NS2,所以它也使用 OTcl(唉),但除此之外这不是问题。现代 Tcl 编程更喜欢使用 list 命令来构造回调而不是字符串替换,因此您可以这样做:

$ns at 0.0 [list $cbr start]
$ns at 0.2 [list $tcp start]

而不是这个:

$ns at 0.0 "$cbr start"
$ns at 0.2 "$tcp start"

但是对象名称很简单,而且这些都是一次性回调,因此不会对安全或性能产生太大影响。

我无法告诉您您是否正确使用了 NS2。我使用完全不同的库编写非常 不同的 Tcl 程序。


如果您注释掉这些 "tcp" 行,您的文件工作正常:

# $ns at 0.2 "$tcp start"
# $ns at 4 "$tcp stop"

运行 搜索所有 ~2,000 个 ns2 模拟文件,显示从未使用过 "$tcp start"$ cd *All-examples/ && grep "tcp start" * ,这可能意味着 "$tcp start" 不是有效的编码方式。

~2,000 个 ns2 模拟文件:all_tcl-examples-2.tar.gz (41.8 MB) https://drive.google.com/file/d/0B7S255p3kFXNUUpUYWJ6TTdseWc/view?usp=sharing

正在查找 tcp 文件:$ cd *All-examples/ && ls | grep -i tcp