# PRF - TP 3 [Sujet](https://moodle.insa-lyon.fr/pluginfile.php/47815/mod_resource/content/4/2018/4tc-prf_tp3-ns2.pdf) ###### tags : `PRF` `TP` ## Introduction ![](https://i.imgur.com/aCiy7dn.png) ## The network simulator ns-2 ![](https://i.imgur.com/KRizLSH.png) ![](https://i.imgur.com/Z1owcY8.png) ## A simple network scenario ![](https://i.imgur.com/hFY2gPB.png) ### Basic ns-2 commands ![](https://i.imgur.com/tPp0Deu.png) > **Question 2.1** > La sortie de ces commandes est le résultat de l'opération. > *Exemple : ```set a 4``` assigne la valeur 4 à la variable. La sortie est donc 4.* ![](https://i.imgur.com/hCfVvus.png) #### Simulator ![](https://i.imgur.com/E6HJDr3.png) #### Nodes ![](https://i.imgur.com/HkwCGEC.png) > **Question 2.2** ``` set n0 [$ns node] set n1 [$ns node] ``` #### Physical links ![](https://i.imgur.com/7Oi8jxI.png) > **Question 2.3** ``` $ns simplex-link $n0 $n1 2Mb 10ms DropTail ``` > Mise en place d'un lien simple de capacité 2Mb/s, avec un délai de propagation de 10ms (temps mis par un paquet pour parcourir le lien) et une politique d'attente FIFO. #### Link and network layers ![](https://i.imgur.com/SD5aciO.png) #### Transport layer ![](https://i.imgur.com/PfHaCDY.png) > **Question 2.4** ``` set udp0 [new Agent/UDP] set sink [new Agent/Null] $ns attach-agent $n0 $udp0 $ns attach-agent $n1 $sink $ns connect $udp0 $sink ``` > On associe un agent UDP au noeud $n_0$ (celui qui envoie les données) et un agent Null au noeud $n_1$ (qui ne fait que recevoir des données). On connecte ensuite les deux agents. #### Application layer ![](https://i.imgur.com/3RmlKFa.png) > **Question 2.5** ``` set cbr0 [new Application/Traffic/CBR] $cbr0 attach-agent $udp0 $ns at 5.0 "$cbr0 start" $ns at 30.0 "$cbr0 stop" ``` > On associe une application CBR à l'agent $udp_0$ (ce qui va nous permettre d'envoyer des données à un débit constant sur le lien). On démarre cette application après 5 secondes de simulation et on l'arrête après 30 secondes. #### Tracing ![](https://i.imgur.com/3Z03pKE.png) > **Question 2.6** ``` set nf [open log.txt w] $ns trace-all $nf ``` > On ouvre un fichier ```log.txt``` dans lequel on va enregistrer toutes les opération seffectuées sur les paquets pendant la simulation (mise en buffer, sortie du buffer, réception, perte). > :warning: Doit être placé au début du code (juste avant l'utilisation des noeuds) #### Starting and ending the simulation ![](https://i.imgur.com/cWmnxRf.png) > **Question 2.7** ``` $ns at 30.1 "close $nf" $ns at 30.2 "$ns halt" $ns run ``` > La commande ```$ns run``` doit être placée à la fin du code. > Lorsqu'on programme plusieurs commandes au même instant avec la commande ```$ns at``` il vaut mieux mettre des instants légèrement différents (ici 30, 30.1 et 30.2) pour éviter de terminer la simulation avant d'avoir fermer le fichier par exemple. ![](https://i.imgur.com/WdFPcyl.png) Script ```simple.tcl``` complet : ``` set ns [new Simulator] set nf [open log-part3.txt w] $ns trace-all $nf set n0 [$ns node] set n1 [$ns node] $ns duplex-link $n0 $n1 2Mb 10ms DropTail set udp0 [new Agent/UDP] set sink [new Agent/Null] $ns attach-agent $n0 $udp0 $ns attach-agent $n1 $sink $ns connect $udp0 $sink set cbr0 [new Application/Traffic/CBR] $cbr0 attach-agent $udp0 $ns at 5.0 "$cbr0 start" $ns at 30.0 "$cbr0 stop" $ns at 30.1 "close $nf" $ns at 30.2 "$ns halt" $ns run ``` ### Trace analysis ![](https://i.imgur.com/fDDr3oq.png) Extrait du fichier ```log.txt``` : ``` + 5 0 1 cbr 210 ------- 0 0.0 1.0 0 0 - 5 0 1 cbr 210 ------- 0 0.0 1.0 0 0 + 5.00375 0 1 cbr 210 ------- 0 0.0 1.0 1 1 - 5.00375 0 1 cbr 210 ------- 0 0.0 1.0 1 1 + 5.0075 0 1 cbr 210 ------- 0 0.0 1.0 2 2 - 5.0075 0 1 cbr 210 ------- 0 0.0 1.0 2 2 r 5.01084 0 1 cbr 210 ------- 0 0.0 1.0 0 0 + 5.01125 0 1 cbr 210 ------- 0 0.0 1.0 3 3 - 5.01125 0 1 cbr 210 ------- 0 0.0 1.0 3 3 r 5.01459 0 1 cbr 210 ------- 0 0.0 1.0 1 1 ``` ![](https://i.imgur.com/Kvnwb3G.png) > **Question 2.8** > La taille des paquets transmis est de 210 bytes. ![](https://i.imgur.com/Yv2SdRy.png) > **Question 2.9** > Ce temps représente le temps mis par le paquet pour passer du buffer au lien (serialization) et le temps passé par le paquet sur le lien (10 ms) > *Calcul temps de serialization : $\frac{210 \cdot 8}{2000} = 0.84ms$* > *On envoie 210 bytes ($210 \cdot 8$ bits) sur un lien à 2Mb/s (2000 b/ms). On obtient donc un temps de serialization égal à 0.84 ms* > Si on ajoute ce temps au temps de propagation, on obtient un délai de 10.84 ms entre l'envoi et la réception du paquet. > Cela correspond à ce qu'on obtient sur la trace. ![](https://i.imgur.com/reBSF9k.png) > **Question 2.10** > On note (adresse.port) > $n_0$ : 0.0 > $n_1$ : 1.0 > Les adresses sont assignées de manière incrémentale (0.0.0.0 puis 0.0.0.1, etc...) ![](https://i.imgur.com/gtS5iua.png) Script ```postprocess.awk``` : ```awk BEGIN { start = 5 # second timestep = 0.1 # second nextstep = start + timestep; } { if($2 > nextstep) { for(f=0; f<=flows; f++) { if(rx[f] > 0) { avg_delay = delay[f]/rx[f]; } else { avg_delay = 0; } printf("%6.2f %4d %8d %8d %10.6f %10.6f\n", nextstep, f, (bytes_tx[f]*8)/(timestep*1000), (bytes_rx[f]*8)/(timestep*1000), avg_delay); bytes_tx[f] = 0; tx[f] = 0; bytes_rx[f] = 0; delay[f] = 0; rx[f] = 0; } nextstep = int($2/timestep)*timestep + timestep; } if($1 == "+") { if($8 > flows) flows = $8; time_buf[$12] = $2; } if($1 == "-") { bytes_tx[$8] += $6; tx[$8]++; } if($1 == "r") { bytes_rx[$8] += $6; delay[$8] += $2 - time_buf[$12]; rx[$8]++; } } ``` > **Question 2.11** > Données générées par ```postprocess.awk``` : > - Temps de simulation > - Numéro du "flow de transmission" (agent qui envoie des données) > - Débit en émission (en b/s) > - Débit en réception (en b/s) > - Délai moyen entre l'émission et la réception d'un paquet ![](https://i.imgur.com/bTDIx4U.png) Extrait du fichier ```postprocess.log``` obtenu après avoir executé le script ```postprocess.awk``` : ``` 5.10 0 453 403 0.010840 0.000000 5.20 0 453 453 0.010840 0.000000 5.30 0 453 453 0.010840 0.000000 5.40 0 436 436 0.010840 0.000000 5.50 0 453 453 0.010840 0.000000 5.60 0 453 453 0.010840 0.000000 5.70 0 436 436 0.010840 0.000000 5.80 0 453 453 0.010840 0.000000 5.90 0 453 453 0.010840 0.000000 6.00 0 436 436 0.010840 0.000000 6.10 0 453 453 0.010840 0.000000 6.20 0 453 453 0.010840 0.000000 6.30 0 436 436 0.010840 0.000000 6.40 0 453 453 0.010840 0.000000 6.50 0 453 453 0.010840 0.000000 6.60 0 436 436 0.010840 0.000000 ``` > **Question 2.12** > Le débit en émission varie entre 453 kb/s et 436 kb/s. On peut considérer ce débit comme étant constant car les calculs sont effectués sur un intervalle de 10 ms et le nombre de paquets envoyés peut varier entre deux intervalles. > On observe pas de pertes car le débit de l'application (égal au débit en émission) est inférieur à la capacité physique du lien (2 Mb/s). ## Adding and controlling flows ![](https://i.imgur.com/UyGn8Ip.png) > **Question 3.1** ``` set udp1 [new Agent/UDP] $udp0 set fid_ 0 $udp1 set fid_ 1 $ns attach-agent $n0 $udp1 $ns connect $udp1 $sink ``` > On créé un nouvel agent UDP qu'on associe au noeud $n_0$. On paramètre les identifier de chaque agent pour pouvoir les différencier. > On connect le nouvel agent au récepteur (agent sink associé au noeud $n_1$). ![](https://i.imgur.com/MrhgXXS.png) > **Question 3.2** ``` set cbr1 [new Application/Traffic/CBR] $cbr1 set rate_ 1.8Mb $cbr1 set packetSize_ 450 $cbr1 set maxpkts_ 5000 $cbr1 attach-agent $udp1 $ns at 15.0 "$cbr1 start" ``` > On créé une nouvelle application CBR qu'on associé à l'agent $udp_1$ > On paramètres son débit à 1,8 Mb/s et la taille des paquets à 450 bytes (nécessaire pour envoyer un paquet toute les 2 ms). On paramètre aussi le nombre maximum de paquets à envoyer (ici 5000). Cette application démarrera après 15 s de simulation. > *Calcul taille des paquets : $\frac{1.8 \cdot 10^6 \cdot 2 \cdot 10^{-3}}{8} = 450$. On multiplie la capacité d'envoi (1,8 Mb/s)sur une seconde par 2 ms pour obtenir le nombre de bits à envoyer dans un intervalle de 2 ms. On divise par 8 pour obtenir un résultat en bytes* ![](https://i.imgur.com/XUMb7L3.png) Extrait de ```log-part3.txt``` : ``` r 15.68008 0 1 cbr 450 ------- 1 0.1 1.0 298 3124 r 15.68092 0 1 cbr 210 ------- 0 0.0 1.0 2826 3125 - 15.6816 0 1 cbr 450 ------- 1 0.1 1.0 305 3135 + 15.682 0 1 cbr 450 ------- 1 0.1 1.0 341 3190 r 15.68272 0 1 cbr 450 ------- 1 0.1 1.0 300 3127 - 15.6834 0 1 cbr 450 ------- 1 0.1 1.0 306 3136 r 15.68356 0 1 cbr 210 ------- 0 0.0 1.0 2827 3128 + 15.68375 0 1 cbr 210 ------- 0 0.0 1.0 2849 3191 + 15.684 0 1 cbr 450 ------- 1 0.1 1.0 342 3192 d 15.684 0 1 cbr 450 ------- 1 0.1 1.0 342 3192 - 15.6852 0 1 cbr 210 ------- 0 0.0 1.0 2830 3137 r 15.68536 0 1 cbr 450 ------- 1 0.1 1.0 301 3129 + 15.686 0 1 cbr 450 ------- 1 0.1 1.0 343 3193 - 15.68604 0 1 cbr 450 ------- 1 0.1 1.0 307 3138 ``` > **Question 3.3** > On observe maintenant des pertes car le débit cumulé des deux applications est supérieur à la capicité du lien ($1.8 + 0.4 = 2.2 > 2$). Le noeud $n_0$ ne peut plus envoyer tous les paquets sur le lien donc son buffer se remplit. Quand le buffer est plein, les paquets sont alors refusés. ![](https://i.imgur.com/uuFcira.png) > **Question 3.4** > Script ```postprocess.awk``` après modifications : ``` BEGIN { start = 5 # second timestep = 0.1 # second nextstep = start + timestep; } { if($2 > nextstep) { for(f=0; f<=flows; f++) { if(rx[f] > 0) { avg_delay = delay[f]/rx[f]; lost_rate = lx[f]/(lx[f]+rx[f]); } else { avg_delay = 0; lost_rate = 0; } printf("%6.2f %4d %8d %8d %10.6f %10.6f\n", nextstep, f, (bytes_tx[f]*8)/(timestep*1000), (bytes_rx[f]*8)/(timestep*1000), avg_delay, lost_rate); bytes_tx[f] = 0; tx[f] = 0; bytes_rx[f] = 0; delay[f] = 0; rx[f] = 0; lx[f] = 0; } nextstep = int($2/timestep)*timestep + timestep; } if($1 == "+") { if($8 > flows) flows = $8; time_buf[$12] = $2; } if($1 == "-") { bytes_tx[$8] += $6; tx[$8]++; } if($1 == "r") { bytes_rx[$8] += $6; delay[$8] += $2 - time_buf[$12]; rx[$8]++; } if($1 == "d") { lx[$8]++; } } ``` ![](https://i.imgur.com/vzH5gLW.png) Script ```postprocess.plt``` : (donné par le professeur donc pas d'explications) ``` # set the terminal, i.e., the figure format (eps) and font (Helvetica, 20pt) set term postscript eps enhanced "Helvetica" 20 # reset all options to default, just for precaution reset # set the figure size set size 0.7,0.7 ############## # throughput # ############## # set the figure name set output "tput.eps" # set the x axis set xrange [5:30] set xlabel "Time (s)" set xtics 5,5,30 set mxtics 2 # set the y axis set yrange [0:2000] set ylabel "Throughput (kbps)" set ytics 0,500,2000 set mytics 2 # set the legend (boxed, on the bottom) set key box left width 1 height 0.5 samplen 2 # set the grid (grid lines start from tics on both x and y axis) set grid xtics ytics # plot the data from the log file plot "< awk '$2 == 0 {print}' postprocess.log" u 1:4 t "CBR 0" \ w l lt 1 lw 3 lc rgb "#cc0000", \ "< awk '$2 == 1 {print}' postprocess.log" u 1:4 t "CBR 1" \ w l lt 1 lw 1 lc rgb "#0000cc" ######### # delay # ######### # set the figure name set output "delay.eps" # set the x axis set xrange [5:30] set xlabel "Time (s)" set xtics 5,5,30 set mxtics 2 # set the y axis set yrange [0:100] set ylabel "Delay (ms)" set ytics 0,20,100 set mytics 2 # set the legend (boxed, on the bottom) set key box left width 1 height 0.5 samplen 2 # set the grid (grid lines start from tics on both x and y axis) set grid xtics ytics # plot the data from the log file plot "< awk '$2 == 0 {print}' postprocess.log" u 1:($5*1000) t "CBR 0" \ w l lt 1 lw 3 lc rgb "#cc0000", \ "< awk '$2 == 1 {print}' postprocess.log" u 1:($5*1000) t "CBR 1" \ w l lt 1 lw 1 lc rgb "#0000cc" ########## # losses # ########## # set the figure name set output "loss.eps" # set the x axis set xrange [15:27] set xlabel "Time (s)" set xtics 15,2,27 set mxtics 2 # set the y axis set yrange [0:0.5] set ylabel "Loss ratio" set ytics 0,0.1,0.5 set mytics 2 # set the legend (boxed, on the bottom) set key box right width 1 height 0.5 samplen 2 # set the grid (grid lines start from tics on both x and y axis) set grid xtics ytics # plot the data from the log file plot "< awk '$2 == 0 {print}' postprocess.log" u 1:6 t "CBR 0" \ w l lt 1 lw 3 lc rgb "#cc0000", \ "< awk '$2 == 1 {print}' postprocess.log" u 1:6 t "CBR 1" \ w l lt 1 lw 1 lc rgb "#0000cc" ``` ![](https://i.imgur.com/Rpimbze.png) > **Question 3.5** > ![](https://i.imgur.com/aYCUaph.png) > Il semblerait que quand $udp_1$ démarre, il occupe la bande passante restante (ici 1,6 Mb/s environ). Quand il s'arrête, il y a un burst de débit pour $udp_0$ car tous les paquets qui sont stockés dans le buffer à ce momment sont envoyés en même temps sur le lien (possible grâce à la capacité du lien) ce qui correspond à une quantité de données plus importante que la normale. ![](https://i.imgur.com/jgaAehh.png) > **Question 3.6** > ![](https://i.imgur.com/kNx5K8K.png) > Le délai calculé est le temps écoulé entre l'entrée d'un paquet dans le buffer et sa réception de l'autre côté du lien (temps passé dans le buffer + temps de serialization, temps de propagation). Quand seul $udp_0$ est actif, le débit de l'application est inférieur à la capacité du lien donc le buffer ne contient jamais plus d'un paquet. Au démarrage d'$udp_1$, le débit cumulé est supérieur à la capacité du lien donc le buffer se remplit. Un paquet passe donc plus de temps dans le buffer qu'auparavant et le délai augmente. ![](https://i.imgur.com/vAIBc7E.png) > **Question 3.7** > ![](https://i.imgur.com/VW7ylUb.png) > Selon PFR et SPE, on ne peut pas répondre à cette question