Académique Documents
Professionnel Documents
Culture Documents
4 février 2014
1 Le simulateur ns
1.1 Principe et Architecture
Le simulateur ns permet la description et la simulation de réseaux IP. Le réseau est représenté
(modélisé) par ses sources de trafic (applications), ses protocoles (UDP, TCP), ses routeurs (avec leurs
files d’attente) et les liens qui les relient. Le réseau est ensuite simulé, ce qui produit des traces et
des statistiques. Des outils périphériques permettent l’animation du réseau (nam) ou la conversion vers
d’autres outils (comme par exemple xgraph pour dessiner des courbes).
L’utilisateur décrit le modèle de son réseau, c’est-à-dire les éléments qui le constituent, dans le langage
OTcl (une extension objet du langage tcl). Ce fichier est ensuite passé au simulateur proprement dit.
Celui-ci se nomme ns. Le modèle étant décrit dans le fichier modele.tcl, on exécute :
b52> ns modele.tcl
Il est possible de rajouter des objets réseau au simulateur, en les programmant en C++. Cette
possibilité ne sera pas exploitée dans ce TP.
1
— d’agents de communication, représentant les protocoles de niveau transport (TCP, UDP) ; ces
agents sont attachés aux nœuds et connectés l’un à l’autre, ce qui représente un échange de
données (connexion TCP, flux UDP).
— d’applications qui génèrent le trafic de données selon certaines lois, et se servent des agents de
transport.
De plus, la description d’une expérience de simulation contient les instructions de trace des objets
que l’on veut observer, et les mesures que l’on veut collecter.
Le langage (O)Tcl
Le langage tcl est un langage de scripts. La fin de ligne est le délimiteur d’instructions. Les com-
mentaires commencent par un # et finissent à la fin de ligne.
Les variables ont toujours le type chaîne de caractères (ou liste de chaînes). La valeur de la variable
de nom a est $a. Les variables sont toujours instanciées avant l’exécution d’une instruction, même à
l’intérieur d’une chaîne de caractères.
Le tableau suivant décrit les principales instructions.
2
Instructions de création d’un modèle, et contrôle de la simulation
La simulation se prépare en écrivant un fichier OTcl, disons TP-ns.tcl. On commence par créer le
simulateur
set ns [new Simulator]
Si on veut tracer les événements du simulateur, et si on veut obtenir les données pour l’animation
post mortem, on fait :
$ns trace-all $f
$ns namtrace-all $nf
où f et nf sont des descripteurs de fichier, ouverts auparavant. Attention : ces instructions doivent venir
avant celles de création des objets de la simulation !
Topologie. Ensuite, on crée les nœuds du réseau, puis les liens qui les relient avec leur débit (1Mb par
seconde dans l’exemple ci-dessous) et leur latence (ici, 250ms), et la politique de rejet des paquets en
trop (ici DropTail mais il y en a d’autres comme par exemple Red, etc. . .). On peut aussi préciser le
nombre limite de paquets dans la file d’attente (100 dans l’exemple ci-dessous).
set n1 [$ns node]
set n2 [$ns node]
$ns duplex-link $n1 $n2 1Mb 250ms DropTail
$ns queue-limit $n1 $n2 100
Unités. ns accepte les arguments 5, 5s, 5ms, 5ns pour des durées de temps. Il est conseillé de toujours
mettre l’unité souhaitée pour ne pas se laisser piéger par la valeur par défaut. De même pour les débits
d’information, en b, Mb etc. Attention : pour les débits, B signifie «octet» (Bytes) alors que le défaut est
en bits/s. Pour les tailles de paquets, le défaut est en octets.
Transport. Il faut créer les agents de transport, les attacher aux nœuds et les connecter entre eux.
Parmi les agents disponibles, on trouve Agent/Null, Agent/LossMonitor, Agent/UDP, Agent/TCP et
Agent/TCPSink. Le code est par exemple :
set udp [new Agent/UDP] # crée une source non contrôlée UDP
set trappe [new Agent/Null] # crée un puits d’information
$ns attach-agent $n1 $udp # attache la source à un noeud
$ns attach-agent $n2 $trappe # attache la destination à un autre
$ns connect $udp $trappe # associe la paire origine/destination
Noter qu’il n’est pas nécessaire de spécifier quelle est la route suivie par les paquets d’une paire d’agents :
c’est le simulateur qui calcule les routes les plus courtes. L’agent LossMonitor peut s’utiliser à la place de
Null mais permet en plus de garder trace des pertes (attribut nloss_), paquets et octets reçus (attributs
npkts_ et nbytes_). Utile pour surveiller des flux UDP.
Important : on ne peut pas relier n’importe quel type d’agent à n’importe quel autre. Par exemple,
un agent TCP doit être relié à un TCPSink. Sinon, la connexion TCP ne fonctionnera pas. On ne peut pas
non plus relier plusieurs agents au même «sink». ns le laisse faire mais ça ne fonctionne pas correctement.
Application. Enfin, on crée les sources de trafic, héritant de la classe Application. Le tableau suivant
résume quelques objets et leurs paramètres spécifiques. Tous ont comme attributs packetSize_ (taille
des paquets, qui sera constante) et rate_ (débit en octets/s pendant les périodes on).
3
Classe (<A>=Application) description paramètres
<A>/Traffic/CBR source à débit constant interval_ intervalle entre paquets
(alternative à rate_), maxpkts_ nombre
max de paquets à envoyer
<A>/Traffic/Exponential source «on/off» à durées burst_time_ durée moyenne des périodes «on»
de distribution exponentielle idle_time_ durée moyenne des périodes «off»
<A>/Traffic/Pareto source «on/off» à durées comme Exponential, plus rate_,
de distribution de Pareto paramètre de forme
<A>/Telnet émule une application telnet
<A>/FTP émule une application FTP maxpkts_ nombre max de paquets
Temporisateurs. Il est possible de programmer des événements qui seront exécutés à des dates précises
de la simulation. Par exemple :
$ns at 1.0 "$truc start" # démarre l’application $truc à t=1.0
$ns at 5.0 "$truc stop" # l’arrête à t=5.0
$ns at 10.0 "finish" # invoque la procédure finish à t=10.0
Typiquement, la fin de la simulation se fera par l’invocation d’une procédure chargée du traitement final
des statistiques. Exemple :
proc finish { } {
global ns f nf stat
puts "C’est fini"
close $f # fermeture du fichier de trace (s’il y a)
close $nf # fermeture du fichier de trace animation
puts "Débit = $stat(debit)" # impression d’une statistique
}
On utilisera aussi souvent des procédures qui se re-programment, telle :
proc perpetuelle { } {
global ns
# ici un traitement utile...
4
set now [$ns now] # récupération de la date courante
set delai 0.1 # incrément de temps
$ns after $delai "perpetuelle" # c’est reparti
}
Surveillants de files d’attente. Le contenu de files d’attente peut être surveillé de plusieurs façons.
On a déjà vu les instructions de trace globale. On peut également tracer une file d’attente particulière.
Ici, celle du lien allant de $n1 a $n2 dans le fichier $f :
Où le <type evt> est + pour une arrivée, - pour un départ, d pour une perte de paquet (drop), r pour
une réception de paquet.
Il existe aussi des objets «monitors». On en attache un à une file par
set spy [$ns monitor-queue $n1 $n2 $f]
$spy set pkts_ # nombre de paquets dans la file
À la fin d’une simulation, on voudra par exemple connaître le nombre de paquets perdus pour les
flots tcp et udp. On écrira alors dans la procédure finish :
5
set stats_tcp [$fcl lookup auto 0 0 2] # 2 correspond à l’identifiant du flot tcp (fid_)
set stats_udp [$fcl lookup auto 0 0 1]
Il existe bien évidemment d’autres attributs associés à un flow monitor comme par exemple pdepartures_
ou barrivals_.
Attention : l’appel aux procédures classifier et lookup doit être fait que lorsqu’on est sûr qu’au
moins un paquet de chaque flot a déjà été traité par un flow monitor. Par conséquent, si vous désirez
obtenir des statistiques pour un flux au cours du temps (probabilité de perte, débit), il est nécessaire de
faire appel à la fonction suivante quelques secondes après le début de la génération des paquets par cette
source :
proc init_udp {} {
global flowmon fcl flowstats_udp
$ns at xx "init_udp"
On utilise ensuite l’objet flowstats_udp dans une fonction que vous définissez pour obtenir les
valeurs des attributs désirées.
Lors des expériences, vous serez amener à faire des statistiques (taux de perte, débit, etc. . .). Sous
(O)TCl, le traitement des nombres est assez particulier. Si vous voulez par exemple mesurer le taux de
perte de paquets et que vous connaissez le nombre de paquets perdus et le nombre de paquets générés,
vous calculez le taux de perte à l’aide de syntaxe suivante :
set taux_perte [expr [format %f $nb_paquets_perdus] / [format %f $nb_paquets_générés]]
La commande format vous permet de convertir un nombre et la syntaxe est similaire à celle du C.
Attention : il faut exécuter l’instruction namtrace-all avant de créér la topologie du réseau, sinon cela
ne marchera pas.
Une fois la simulation finie, on appelle nam en passant le nom du fichier trace en argument, ou bien
en le chargeant à partir de l’interface graphique.
Il est possible d’utiliser des couleurs pour visualiser les paquets provenant de la source TCP et de la
source UDP. Pour cela, il suffit de donner un numéro de classe aux agents TCP et UDP de la manière
suivante :
$udp set class_ 1
$tcp set class_ 2
6
$ns color 1 Blue
$ns color 2 Red
et vous regardez ensuite le résultat sous nam.
D’autres instructions utiles pour contrôler l’apparence du réseau dans nam sont :
Elles ont pour effet, respectivement, de colorier et mettre une étiquette à un nœud, de fixer l’orientation
des liens, et de faire apparaître la file d’attente pour le lien en question, avec un angle de 90o (c’est-à-dire :
0.5 × 180o ) par rapport à l’horizontale.
3 Micro-manuel de gnuplot
gnuplot est un outil permettant de dessiner des courbes, soit à partir de fonction définies par l’uti-
lisateur, soit à partir d’un fichier contenant des couples de points.
gnuplot fonctionne habituellement en mode interactif. On entre “gnuplot” (on obtient le “prompt”
gnuplot>), et on entre des commandes. On peut également mettre ces commandes dans un fichier et le
passer en argument à gnuplot. Le programme exécute alors les commandes et termine. Ceci est surtout
utile quand les graphes sont produits dans un fichier (PS, PDF ou autre).
Ces commandes peuvent être par exemple :
>? demande d’aide générale
> help idem
> ?plot demande d’aide sur la fonction “plot”
> lambda=0.5 définition d’un paramètre (une variable) lambda
> f(x) = sin(x)+lambda*x définition d’une fonction de la variable x
> plot [0:10] f(x) dessin de la fonction f sur l’intervalle 0 ≤ x ≤ 10
> plot [0:10] [0:5] f(x) idem mais en restreignant les y à l’intervalle [0, 5]
> set xrange [0:5] fixe l’intervalle des valeurs pour l’axe des abscisses
> plot "toto.dat" dessin du fichier de données toto.dat
> plot "toto.dat" with lines dessin du fichier de données toto.dat en reliant les points
par des droites
> plot "toto.dat" with steps idem mais avec des marches
> plot "toto.dat" with dots idem mais avec des points plus petits
> plot "toto.dat" using ($2):($1) idem, mais en intervertissant x et y (voir le manuel de using).
> plot "toto.dat", f(x) dessin simultané de données et d’une fonction.
> set term postscript configure le format de sortie des graphiques : ici à PostScript.
> set term donne la liste des formats disponibles.
Les fichiers de données acceptés par gnuplot sont formés de nombres, un ou deux par ligne. On peut
utiliser le symbole # pour commenter des lignes. Exemple :
# Fichier de données pour gnuplot crée le 5 mars 2003 en TP
# Première colonne: numéro de client n
# Seconde colonne : date d’arrivée a(n)
#
1 0.234
2 1.456
3 2.789
...
Si on omet la première colonne, gnuplot la remplacera par les abscisses 1,2, etc. Cette colonne
supplémentaire est numérotée “0” quand on utilise plot ... using. Ainsi :
> plot "toto.dat" using 1:0 renverse x et y dans le cas d’une seule colonne.
> plot "toto.dat" using 2:1 renverse x et y dans le cas de deux colonnes.
7
Enfin, il est possible de spécifier des opérations à faire sur les données avant de les placer sur le
graphique. Par exemple :
> plot "toto.dat" using 0:(log($1)/4.0) pour la coordonnée y, remplace la valeur v
de la première colonne par log(v)/4.
D’autres commandes utiles pour décorer les graphiques sont :
> plot "toto.dat" with linespoints variation sur la forme des lignes
> set xlabel "abracadabra" met un titre sur l’axe des abscisses
> set ylabel "hocuspocus" idem pour les ordonnees
> set title "titre de la courbe" met un titre à la courbe