
4 Aperçu du concept
4.1 Abstractions clés
4.1.1 Node (NĆud)
4.1.2 Application (Application)
4.1.3 Channel (Canal)
4.1.4 Net Device (Dispositif réseau)
4.1.5 Assistants topologiques
4.2 Premier script ns-3
4.2.1 Code boilerplate
4.2.2 Modules connectés
4.2.3 Espace de noms ns3
4.2.4 Journalisation
4.2.5 Fonction principale
4.2.6 Utilisation des assistants topologiques
4.2.7 Utilisation de l'Application
4.2.8 Simulateur
4.2.9 Assemblage de votre scénario
4.3 Code source de ns-3
Chapitre 4
Aperçu du concept
La premiÚre chose que nous devons faire avant de commencer à étudier ou à écrire du code ns-3 est d'expliquer quelques concepts fondamentaux et abstractions dans le systÚme. Beaucoup d'entre eux peuvent sembler évidents pour certains, mais nous vous recommandons de prendre le temps de lire cette section pour vous assurer que vous commencez sur une base solide.
4.1 Abstractions clés
Dans cette section, nous examinerons certains termes qui sont généralement utilisés dans le réseau, mais qui ont une signification particuliÚre dans ns-3.
4.1.1 Node (NĆud)
Dans le jargon Internet, un dispositif informatique qui se connecte au rĂ©seau est appelĂ© un hĂŽte ou parfois un systĂšme terminal. Pour cette raison, Ă©tant donnĂ© que ns-3 est un simulateur de rĂ©seau et non un simulateur Internet, nous Ă©vitons dĂ©libĂ©rĂ©ment d'utiliser le terme hĂŽte, car il est Ă©troitement liĂ© Ă Internet et Ă ses protocoles. Ă la place, nous utilisons un terme plus gĂ©nĂ©ral, Ă©galement utilisĂ© par d'autres simulateurs, qui trouve son origine dans la thĂ©orie des graphes : nĆud (node).
Dans ns-3, l'abstraction de base d'un dispositif informatique est appelĂ©e nĆud. Cette abstraction est reprĂ©sentĂ©e en C++ par la classe Node. La classe NodeNode (nĆud) fournit des mĂ©thodes pour gĂ©rer les reprĂ©sentations des dispositifs informatiques dans les simulations.
Vous devez comprendre NĆud comme un ordinateur auquel vous ajouterez des fonctionnalitĂ©s. Vous ajoutez des choses telles que des applications, des piles de protocoles et des cartes d'extension avec des pilotes, permettant Ă l'ordinateur d'effectuer un travail utile. Nous utilisons le mĂȘme modĂšle de base dans ns-3.
4.1.2 Application (Application)
En général, les logiciels informatiques se divisent en deux grandes catégories. Les logiciels systÚme organisent diverses ressources informatiques telles que la mémoire, les cycles du processeur, le disque, le réseau, etc., selon un certain modÚle de calcul. Les logiciels systÚme n'utilisent généralement pas ces ressources pour effectuer des tùches qui apportent un bénéfice direct à l'utilisateur. Pour atteindre un objectif spécifique, l'utilisateur lance généralement une application qui obtient et utilise les ressources contrÎlées par le logiciel systÚme.
Souvent, la ligne de sĂ©paration entre le logiciel systĂšme et le logiciel applicatif se trace au niveau du changement de privilĂšges qui se produit dans les appels systĂšmes. Dans nsâ3, il n'y a pas de vĂ©ritable concept de systĂšme d'exploitation et donc pas de notions de niveaux de privilĂšges ou d'appels systĂšme. Cependant, nous avons l'idĂ©e d'application. Tout comme dans le "monde rĂ©el", pour accomplir des tĂąches, les applications fonctionnent sur des ordinateurs, les applications nsâ3 fonctionnent sur les nĆuds nsâ3 pour gĂ©rer les simulations dans un monde simulĂ©.
Dans nsâ3, l'abstraction de base pour un programme utilisateur qui gĂ©nĂšre une certaine activitĂ© pour la modĂ©lisation est l'application. Cette abstraction est reprĂ©sentĂ©e en C++ par la classe Application. La classe Application fournit des mĂ©thodes pour gĂ©rer dans les simulations les reprĂ©sentations de notre version des applications de niveau utilisateur. Il est attendu des dĂ©veloppeurs qu'ils spĂ©cialisent la classe Application pour crĂ©er de nouvelles applications dans un sens orientĂ© objet. Dans ce guide, nous utiliserons les spĂ©cialisations de la classe Application, appelĂ©es UdpEchoClientApplication et UdpEchoServerApplication. Comme il fallait s'y attendre, ces applications constituent un ensemble d'applications client/serveur utilisĂ©es pour gĂ©nĂ©rer et simuler des paquets rĂ©seau en Ă©cho.
4.1.3 Channel (Canal)
Dans le monde rĂ©el, un ordinateur peut ĂȘtre connectĂ© Ă un rĂ©seau. Souvent, les milieux par lesquels les donnĂ©es sont transmises dans ces rĂ©seaux sont appelĂ©s des canaux. Lorsque vous connectez un cĂąble Ethernet Ă une prise murale, vous connectez l'ordinateur Ă un canal de communication Ethernet. Dans le monde simulĂ© de nsâ3, un nĆud est connectĂ© Ă un objet reprĂ©sentant un canal de communication. Ici, la principale abstraction de la sous-rĂ©seau de communication est appelĂ©e canal et est reprĂ©sentĂ©e dans C++ par la classe Channel.
Classe ChannelChannel fournit des mĂ©thodes pour gĂ©rer l'interaction des objets de sous-rĂ©seau et leur connexion Ă des nĆuds. Les canaux peuvent Ă©galement ĂȘtre spĂ©cialisĂ©s par les dĂ©veloppeurs en termes de programmation orientĂ©e objet. La spĂ©cialisation d'un canal peut modĂ©liser quelque chose d'aussi simple qu'un fil. Un canal spĂ©cialisĂ© peut Ă©galement modĂ©liser des choses complexes comme un grand commutateur Ethernet ou un espace tridimensionnel rempli d'obstacles dans le cas des rĂ©seaux sans fil.
Nous allons utiliser dans ce guide des versions spécialisées de canal appelées CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel et WifiChannelWifiChannel. CsmaChannel, par exemple, modélise une version de la sous-réseau de communication qui implémente un environnement de communication à accÚs multiple avec contrÎle de porteuse. Cela nous donne une fonctionnalité similaire à celle de l'Ethernet.
4.1.4 Net Device (Dispositif réseau)
Auparavant, si vous vouliez connecter un ordinateur Ă un rĂ©seau, vous deviez acheter un cĂąble rĂ©seau spĂ©cifique et un dispositif matĂ©riel appelĂ© (dans le jargon PC) carte d'extension, qui devait ĂȘtre installĂ©e dans l'ordinateur. Si certaines fonctions rĂ©seau Ă©taient implĂ©mentĂ©es sur la carte d'extension, elles Ă©taient appelĂ©es cartes d'interface rĂ©seau ou cartes rĂ©seau. Aujourd'hui, la plupart des ordinateurs sont Ă©quipĂ©s de matĂ©riel d'interface rĂ©seau intĂ©grĂ©, et les utilisateurs ne les considĂšrent pas comme des dispositifs sĂ©parĂ©s.
Une carte réseau ne fonctionnera pas sans un pilote logiciel qui gÚre son matériel. Dans Unix (ou Linux), une partie du matériel est classée comme un périphérique. Les périphériques sont gérés à l'aide de pilotes de périphérique, et les dispositifs réseau (NIC) sont gérés à l'aide de pilotes de dispositifs réseau (network device drivers) et ont un terme collectif appelé dispositifs réseau (net devices). Dans Unix et Linux, vous accédez aux périphériques réseau par des noms tels que eth0.
Dans ns-3, l'abstraction du pĂ©riphĂ©rique rĂ©seau englobe Ă la fois le pilote logiciel et le matĂ©riel simulĂ©. Lors de la simulation, le pĂ©riphĂ©rique rĂ©seau est « installĂ© » dans un nĆud pour lui permettre de communiquer avec d'autres nĆuds via des canaux. Comme sur un ordinateur rĂ©el, un nĆud peut ĂȘtre connectĂ© Ă plusieurs canaux via plusieurs pĂ©riphĂ©riques. NetDevices.
L'abstraction rĂ©seau du pĂ©riphĂ©rique est reprĂ©sentĂ©e dans la classe C++ NetDevice. La classe NetDevice fournit des mĂ©thodes pour gĂ©rer les connexions avec les objets Node et Channel ; et peut ĂȘtre spĂ©cialisĂ©e par les dĂ©veloppeurs en termes de programmation orientĂ©e objet. Dans ce guide, nous utiliserons plusieurs versions spĂ©cialisĂ©es de NetDevice appelĂ©es CsmaNetDevice, PointToPointNetDevice et WifiNetDevice. Tout comme l'adaptateur rĂ©seau Ethernet est conçu pour fonctionner avec le Ethernet, CsmaNetDevice est conçu pour fonctionner avec le CsmaChannel, PointToPointNetDevice est conçu pour fonctionner avec le PointToPointChannel, et WifiNetDevice â est conçu pour fonctionner avec le WifiChannel.
4.1.5 Assistants topologiques
Dans un rĂ©seau rĂ©el, vous trouverez des ordinateurs hĂŽtes avec des cartes rĂ©seau ajoutĂ©es (ou intĂ©grĂ©es). Dans ns-3, nous dirions que vous verrez des nĆuds avec des NetDevices connectĂ©s. Dans un grand rĂ©seau simulĂ©, vous devrez organiser des connexions entre plusieurs objets. NĆud, NetDevice et Channel.
Ătant donnĂ© que la connexion des NetDevices aux nĆuds, des NetDevices aux canaux, l'attribution d'adresses IP, etc. dans ns-3 sont des tĂąches courantes, afin de rendre cela aussi simple que possible, nous fournissons ce qu'on appelle des helpers topologiques. Par exemple, pour crĂ©er un NetDevice, vous devez effectuer de nombreuses opĂ©rations dans le cĆur de ns-3, ajouter une adresse MAC, installer ce pĂ©riphĂ©rique rĂ©seau dans un Node, configurer la pile de protocoles du nĆud, puis connecter le NetDevice au Channel. Encore plus d'opĂ©rations seront nĂ©cessaires pour connecter plusieurs pĂ©riphĂ©riques Ă des canaux multipoints, puis relier des rĂ©seaux distincts Ă un rĂ©seau unifiĂ© (Internetworks). Nous fournissons des objets d'assistance topologique qui, pour votre commoditĂ©, regroupent ces nombreuses opĂ©rations dans un modĂšle facile Ă utiliser.
4.2 Premier script ns-3
Si vous avez installé le systÚme comme suggéré ci-dessus, vous aurez un release ns-3 dans un répertoire nommé repos dans votre répertoire personnel. Accédez au répertoire release
Si vous n'avez pas ce rĂ©pertoire, cela signifie que vous n'avez pas spĂ©cifiĂ© le rĂ©pertoire de sortie lors de la compilation de la version de nsâ3, exĂ©cutez la compilation comme suit :
$ ./waf configure --build-profile=release --out=build/release,
$ ./waf build
là , vous devriez voir une structure de répertoire ressemblant à ceci :
AUTHORS examples scratch utils waf.bat*
bindings LICENSE src utils.py waf-tools
build ns3 test.py* utils.pyc wscript
CHANGES.html README testpy-output VERSION wutils.py
doc RELEASE_NOTES testpy.supp waf* wutils.pycAllez dans le rĂ©pertoire examples/tutorial. Vous devriez voir un fichier nommĂ© first.cc. C'est un script qui crĂ©era une connexion point Ă point simple entre deux nĆuds et transmettra un paquet entre eux. Regardons ce script ligne par ligne, alors ouvrons first.cc dans votre Ă©diteur prĂ©fĂ©rĂ©.
4.2.1 Code boilerplate
La premiÚre ligne du fichier est la ligne de mode de l'éditeur emacs. Elle indique à emacs les conventions de formatage (style de codage) que nous utiliserons dans notre code source.
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */C'est toujours une question assez polĂ©mique, donc nous devons clarifier pour lâĂ©vacuer immĂ©diatement. Le projet nsâ3, comme la plupart des grands projets, a adoptĂ© un style de codage auquel tout le code fourni doit se conformer. Si vous souhaitez contribuer votre code au projet, vous devrez finalement vous conformer au standard de codage de nsâ3, tel que dĂ©crit dans le fichier doc/codingstd.txt ou prĂ©sentĂ© sur la page web du projet : .
Nous vous recommandons de vous habituer Ă lâapparence du code nsâ3 et d'appliquer ce standard chaque fois que vous travaillez avec notre code. Toute l'Ă©quipe de dĂ©veloppement et les contributeurs sont d'accord avec cela aprĂšs un peu de grognement. La ligne de mode emacs ci-dessus facilite le bon formatage si vous utilisez l'Ă©diteur emacs.
Le simulateur nsâ3 est sous licence avec la GNU General Public License. Vous verrez l'en-tĂȘte lĂ©gal correspondant de la GNU dans chaque fichier de distribution de nsâ3. Vous pouvez souvent voir un avis de droit d'auteur pour l'une des institutions participant au projet nsâ3 au-dessus du texte de la GPL et de l'auteur, affichĂ© ci-dessous.
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/4.2.2 Modules connectés
Le code proprement dit commence par une série d'instructions d'inclusion (include).
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"Pour aider nos utilisateurs de scripts de haut niveau Ă gĂ©rer le grand nombre de fichiers d'en-tĂȘte prĂ©sents dans le systĂšme, nous les regroupons selon leur utilisation en grands modules. Nous fournissons un fichier d'en-tĂȘte qui chargera rĂ©cursivement tous les fichiers d'en-tĂȘte utilisĂ©s dans ce module. Au lieu de chercher quel en-tĂȘte vous avez besoin et de peut-ĂȘtre obtenir la bonne liste de dĂ©pendances, nous vous offrons la possibilitĂ© de charger un groupe de fichiers avec un grand niveau de dĂ©tails. Ce n'est pas la mĂ©thode la plus efficace, mais elle rend certainement l'Ă©criture de scripts beaucoup plus simple.
Chacun des fichiers inclus dans nsâ3 est placĂ© dans un rĂ©pertoire nommĂ© ns3 (sous-rĂ©pertoire de construction), afin d'Ă©viter les conflits de noms de fichiers pendant le processus de construction. Le fichier ns3/core-module.h correspond au module nsâ3 que vous trouverez dans le rĂ©pertoire src/core dans la version que vous avez installĂ©e. Dans la liste de ce rĂ©pertoire, vous trouverez un grand nombre de fichiers d'en-tĂȘte. Lorsque vous faites une construction, Waf place les fichiers d'en-tĂȘte publics dans le rĂ©pertoire ns3 dans le sous-rĂ©pertoire build/debug
Si vous n'avez pas ce rĂ©pertoire, cela signifie que vous n'avez pas spĂ©cifiĂ© le rĂ©pertoire de sortie lors de la compilation de la version de nsâ3, exĂ©cutez la compilation comme suit :
$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf build
ou
$ ./waf configure --build-profile=optimized --out=build/optimized
$ ./waf build
ou build/optimized, selon votre configuration. Waf gĂ©nĂšre Ă©galement automatiquement un fichier d'inclusion de module pour charger tous les fichiers d'en-tĂȘte publics. Puisque vous suivez bien sĂ»r ce guide Ă la lettre, vous avez dĂ©jĂ effectuĂ©
$ ./waf -d debug --enable-examples --enable-tests configurepour configurer le projet pour effectuer des constructions de débogage, y compris des exemples et des tests. Vous avez également exécuté
$ ./wafpour construire le projet. Donc maintenant, lorsque vous regardez dans le rĂ©pertoire ../..../build/debug/ns3, vous trouverez parmi d'autres les fichiers d'en-tĂȘte des quatre modules mentionnĂ©s ci-dessus. Vous pouvez jeter un coup d'Ćil au contenu de ces fichiers et constater qu'ils incluent tous les fichiers publics utilisĂ©s par les modules correspondants.
4.2.3 Espace de noms ns3
La ligne suivante dans le script first.cc est la déclaration de l'espace de noms.
using namespace ns3;Le projet nsâ3 est rĂ©alisĂ© dans l'espace de noms C++ appelĂ© ns3. Cela regroupe toutes les dĂ©clarations liĂ©es Ă nsâ3 en dehors de l'espace de noms global, ce qui, nous l'espĂ©rons, facilitera l'intĂ©gration avec d'autres codes. L'utilisation de l'opĂ©rateur C++ introduit l'espace de noms nsâ3 dans la rĂ©gion dĂ©clarative actuelle (globale). C'est une maniĂšre Ă©laborĂ©e de dire qu'aprĂšs cette dĂ©claration, vous n'aurez plus besoin d'utiliser l'opĂ©rateur de rĂ©solution ns3::scope devant tout le code nsâ3 pour l'utiliser. Si vous n'ĂȘtes pas familier avec les espaces de noms, consultez pratiquement n'importe quel manuel de C++ et comparez l'espace de noms ns3 avec l'utilisation de l'espace de noms std et des dĂ©clarations. using namespace std; dans les exemples travaillant avec l'opĂ©rateur de sortie cout et les flux.
4.2.4 Journalisation
La ligne suivante du script est la suivante :
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");Nous utiliserons cette dĂ©claration comme un point pratique pour discuter de notre systĂšme de documentation. DoxygenSi vous regardez le site web du projet nsâ3, vous trouverez un lien vers « Documentation » dans la barre de navigation. Si vous cliquez sur ce lien, vous serez dirigĂ© vers notre page de documentation. Il y a un lien vers le « Dernier release », qui vous mĂšnera Ă la documentation de la derniĂšre version stable de nsâ3. Si vous choisissez le lien « API Documentation », vous accĂ©derez Ă la page de la documentation API de nsâ3.
Sur le cĂŽtĂ© gauche de la page, vous trouverez une reprĂ©sentation graphique de la structure de la documentation. Un bon point de dĂ©part est le « livre » Modules nsâ3 dans l'arborescence de navigation nsâ3. Si vous dĂ©veloppez Modules, vous verrez une liste de la documentation des modules nsâ3. Comme discutĂ© ci-dessus, le concept de module ici est directement liĂ© aux fichiers inclus dans le module ci-dessus. Le sous-systĂšme de journalisation (logging) de nsâ3 est discutĂ© dans la section Utilisation du module de journalisation, donc nous y reviendrons plus tard dans ce guide, mais vous pouvez en apprendre davantage sur la dĂ©claration ci-dessus en consultant le module Noyau, puis en ouvrant le livre Outils de dĂ©bogage, puis en sĂ©lectionnant la page Journalisation. Cliquez sur Journalisation.
Vous devez maintenant consulter la documentation Doxygen pour le module. Journalisation. Dans la liste des macros en haut de la page, vous verrez une entrée pour NS_LOG_COMPONENT_DEFINE. Avant de cliquer sur le lien, assurez-vous de consulter la « Description détaillée » du module de journalisation afin de comprendre son fonctionnement global. Pour cela, vous pouvez faire défiler vers le bas ou sélectionner « Plus⊠» sous le diagramme.
Une fois que vous avez une vue d'ensemble de ce qui se passe, allez-y et consultez la documentation sur le NS_LOG_COMPONENT_DEFINE spécifique. Je ne vais pas dupliquer la documentation ici, mais en résumé, cette ligne déclare un composant de journalisation nommé FirstScriptExample, qui permet d'activer et de désactiver l'enregistrement des messages dans la console par un lien sur le nom.
4.2.5 Fonction principale
Dans les lignes suivantes du script, vous verrez
int
main (int argc, char *argv[])
{ C'est simplement la déclaration de la fonction principale de votre programme (script). Comme dans tout programme en C++, vous devez définir la fonction principale, qui s'exécute en premier. Il n'y a rien de spécial ici. Votre script ns-3 est simplement un programme C++. La ligne suivante définit la résolution temporelle à 1 nanoseconde, ce qui est la valeur par défaut :
Time::SetResolution (Time::NS);La rĂ©solution temporelle ou simplement la rĂ©solution est la plus petite valeur temporelle pouvant ĂȘtre utilisĂ©e (la plus petite diffĂ©rence reprĂ©sentable entre deux valeurs temporelles). Vous ne pouvez changer la rĂ©solution qu'une seule fois. Le mĂ©canisme qui permet cette flexibilitĂ© consomme de la mĂ©moire, donc une fois que la rĂ©solution est explicitement dĂ©finie, nous libĂ©rons la mĂ©moire, empĂȘchant ainsi de futures mises Ă jour. (Si vous ne dĂ©finissez pas explicitement la rĂ©solution, elle sera par dĂ©faut d'une nanoseconde, et la mĂ©moire sera libĂ©rĂ©e au dĂ©but de la simulation.)
Les deux lignes suivantes du script sont utilisées pour activer deux composants de journalisation intégrés aux applications EchoClient et EchoServer:
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);Si vous avez lu la documentation du composant Logging, vous remarquerez qu'il existe plusieurs niveaux de détail d'enregistrement que vous pouvez activer sur chaque composant. Ces deux lignes de code activent la journalisation de débogage au niveau INFO pour les clients et serveurs écho. à ce niveau, l'application imprimera des messages lors de l'envoi et de la réception de paquets pendant la simulation.
Nous allons maintenant passer directement à la création de la topologie et au démarrage de la simulation. Nous utiliserons des objets d'assistance topologique pour faciliter cette tùche.
4.2.6 Utilisation des assistants topologiques
Les deux lignes suivantes de code dans notre script vont en fait créer des objets Node ns-3 qui représenteront des ordinateurs dans la simulation.
NodeContainer nodes;
nodes.Create(2);Avant de continuer, trouvons la documentation pour la classe NodeContainer. Une autre façon d'accéder à la documentation pour cette classe est à travers l'onglet Classes sur les pages Doxygen. Si vous avez déjà ouvert Doxygen, faites simplement défiler vers le haut de la page et sélectionnez l'onglet Classes. Vous devriez voir un nouvel ensemble d'onglets, dont l'un liste les classes. Sous cet onglet, vous verrez la liste de toutes les classes ns-3. Faites défiler vers le bas jusqu'à ns3::NodeContainer. Lorsque vous trouvez la classe, sélectionnez-la pour accéder à la documentation de cette classe.
Comme nous le savons, l'une de nos abstractions clĂ©s est le nĆud. Il reprĂ©sente un ordinateur auquel nous allons ajouter des Ă©lĂ©ments tels que des piles de protocoles, des applications et des cartes pĂ©riphĂ©riques. L'assistant topologique NodeContainer offre un moyen pratique de crĂ©er, gĂ©rer et accĂ©der Ă tous les objets NĆud, que nous crĂ©ons pour lancer la simulation. La premiĂšre ligne ci-dessus dĂ©clare simplement NodeContainer, que nous appelons nodes. La deuxiĂšme ligne appelle la mĂ©thode Create pour l'objet nodes et demande au conteneur de crĂ©er deux nĆuds. Comme dĂ©crit dans Doxygen, le conteneur demande Ă la systĂšme ns-3 de crĂ©er deux objets NĆud et conserve les pointeurs vers ces objets Ă l'intĂ©rieur.
Les nĆuds créés dans le script ne font rien pour le moment. La prochaine Ă©tape dans la construction de la topologie est de connecter nos nĆuds au rĂ©seau. La forme de rĂ©seau la plus simple que nous soutenons est une connexion point Ă point entre deux nĆuds. Nous allons maintenant Ă©tablir cette connexion.
PointToPointHelper
Nous établissons une connexion bidirectionnelle en suivant un modÚle familier, utilisant un objet auxiliaire topologique pour effectuer le travail de bas niveau nécessaire à la connexion. Rappelons que nos deux principales abstractions NetDevice et Channel. Dans le monde réel, ces termes correspondent grosso modo à des cartes de périphériques et à des cùbles réseau. En général, ces deux éléments sont étroitement liés, et personne ne peut compter sur l'échange, par exemple, d'appareils Ethernet via un canal sans fil. Nos aides topologiques suivent cette connexion étroite, et donc, dans ce scénario, vous utiliserez un seul objet PointToPointHelper pour configurer et connecter des objets ns-3 PointToPointNetDevice et PointToPointChannel. Les trois lignes suivantes dans le script :
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));La premiĂšre ligne,
PointToPointHelper pointToPoint;crée une instance de l'objet dans la pile PointToPointHelper. Du point de vue de haut niveau, la ligne suivante,
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));indique à l'objet PointToPointHelper d'utiliser la valeur « 5 Mbps » (cinq mégabits par seconde) comme «DataRate».
D'un point de vue plus spécifique, la ligne « DataRate » correspond à ce que nous appelons un attribut PointToPointNetDevice. Si vous regardez Doxygen pour la classe ns3::PointToPointNetDevice et dans la documentation de la méthode GetTypeId vous trouverez une liste des attributs définis pour le dispositif. Parmi eux, il y aura l'attribut «DataRate». La plupart des objets visibles par l'utilisateur de ns-3 ont des listes d'attributs similaires. Nous utilisons ce mécanisme pour configurer simplement la simulation sans recompilation, comme vous le verrez dans la section suivante.
De mĂȘme que «DataRate» dans PointToPointNetDevice, vous trouverez l'attribut « Delay », associĂ© Ă PointToPointChannel. La ligne finale,
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));dit PointToPointHelper utilise la valeur « 2 ms » (deux millisecondes) comme valeur de délai de propagation sur le canal point à point qu'il crée ensuite.
NetDeviceContainer
Ă ce stade, notre script contient NodeContainer, qui contient deux nĆuds. Nous avons PointToPointHelper, qui est prĂ©parĂ© pour crĂ©er des objets PointToPointNetDevices et les connecter Ă l'aide d'un objet PointToPointChannel. Tout comme nous avons utilisĂ© un objet auxiliaire de topologie NodeContainer pour crĂ©er des nĆuds, nous demanderons Ă PointToPointHelper de s'occuper pour nous de la crĂ©ation, de la configuration et de la mise en place de nos dispositifs. Nous aurons besoin d'une liste de tous les objets créés NetDevice, c'est pourquoi nous utilisons NetDeviceContainer pour leur stockage de la mĂȘme maniĂšre que nous avons utilisĂ© NodeContainer pour le stockage des nĆuds que nous avons créés. Les deux lignes de code suivantes,
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);terminent la configuration des appareils et du canal. La premiĂšre ligne dĂ©clare le conteneur d'appareils mentionnĂ© ci-dessus, et la seconde exĂ©cute le travail principal. La mĂ©thode Installer de l'installation PointToPointHelper prend NodeContainer comme paramĂštre. Ă l'intĂ©rieur NetDeviceContainer pour chaque nĆud prĂ©sent dans NodeContainer est créé (pour la communication point Ă point, il doit y en avoir exactement deux) PointToPointNetDevice est créé et stockĂ© dans le conteneur d'appareils. PointToPointChannel est créé, et deux y sont joints PointToPointNetDevices. Une fois les objets créés, les attributs stockĂ©s dans PointToPointHelper, sont utilisĂ©s pour initialiser les attributs correspondants dans les objets créés.
AprĂšs l'appel de pointToPoint.Install (nodes) , nous aurons deux nĆuds, chacun avec un dispositif rĂ©seau "point Ă point" installĂ© et un canal "point Ă point" entre eux. Les deux appareils seront configurĂ©s pour transmettre des donnĂ©es Ă une vitesse de cinq mĂ©gabits par seconde avec un dĂ©lai de transmission sur le canal de deux millisecondes.
InternetStackHelper
Nous avons maintenant configurĂ© les nĆuds et les dispositifs, mais nos nĆuds n'ont pas de piles de protocoles installĂ©es. Les deux lignes de code suivantes s'occuperont de cela.
InternetStackHelper stack;
stack.Install (nodes);InternetStackHelper reprĂ©sente un assistant topologique pour les piles Internet, semblable Ă PointToPointHelper pour les dispositifs rĂ©seau Ă deux points. La mĂ©thode Installer prend NodeContainer comme paramĂštre. Lors de l'exĂ©cution, elle installera la pile Internet (TCP, UDP, IP, etc.) sur chaque nĆud du conteneur.
Ipv4AddressHelper
Ensuite, nous devons associer nos dispositifs aux adresses IP. Nous fournissons un assistant topologique pour gérer la distribution des adresses IP. La seule API visible pour l'utilisateur est la configuration de l'adresse IP de base et du masque de réseau à utiliser lors de la distribution effective des adresses (cela se fait à un niveau inférieur au sein de l'assistant). Les deux lignes de code suivantes dans notre exemple de script first.cc,
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");dĂ©clare un objet auxiliaire d'adresse et lui indique qu'il doit commencer Ă attribuer des adresses IP Ă partir du rĂ©seau 10.1.1.0, en utilisant le masque de sous-rĂ©seau 255.255.255.0 pour la dĂ©termination. Par dĂ©faut, les adresses attribuĂ©es commenceront par un et augmenteront de maniĂšre monotone, ainsi la premiĂšre adresse attribuĂ©e de cette plage sera 10.1.1.1, puis 10.1.1.2, etc. En rĂ©alitĂ©, au niveau le plus bas, le systĂšme ns-3 mĂ©morise toutes les adresses IP attribuĂ©es et gĂ©nĂšre une erreur fatale si vous avez accidentellement créé une situation oĂč la mĂȘme adresse est gĂ©nĂ©rĂ©e deux fois (d'ailleurs, cette erreur est difficile Ă dĂ©boguer).
La ligne de code suivante,
Ipv4InterfaceContainer interfaces = address.Assign (devices);effectue l'attribution effective de l'adresse. Dans ns-3, nous établissons une liaison entre l'adresse IP et le dispositif en utilisant l'objet Ipv4Interface. Tout comme nous avons parfois besoin d'une liste des dispositifs réseau créés par l'assistant pour une utilisation ultérieure, nous avons parfois besoin d'une liste d'objets Ipv4Interface. Ipv4InterfaceContainer fournit cette fonctionnalité.
Nous avons construit un rĂ©seau point Ă point, avec des piles installĂ©es et des adresses IP attribuĂ©es. Maintenant, nous avons besoin d'applications sur chaque nĆud pour gĂ©nĂ©rer du trafic.
4.2.7 Utilisation de l'Application
Une autre des abstractions clés du systÚme ns-3 est Application (application). Dans ce scénario, nous utilisons deux spécialisations de la classe de base Application ns-3 appelée UdpEchoServerApplication et UdpEchoClientApplication. Comme dans les cas précédents, nous utilisons des objets auxiliaires pour configurer et gérer les objets de base. Ici, nous utilisons UdpEchoServerHelper et UdpEchoClientHelperdes objets pour nous simplifier la vie.
UdpEchoServerHelper
Les lignes de code suivantes dans notre exemple de script first.cc sont utilisĂ©es pour configurer l'application de serveur UDP Ă©cho sur l'un des nĆuds que nous avons créés prĂ©cĂ©demment.
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));La premiĂšre ligne de code dans le fragment ci-dessus crĂ©e UdpEchoServerHelper. Comme d'habitude, ce n'est pas une application en soi, c'est un objet qui nous aide Ă crĂ©er de vĂ©ritables applications. Un de nos accords consiste Ă transmettre les attributs nĂ©cessaires au constructeur de l'objet auxiliaire (assistant). Dans ce cas, l'assistant ne peut rien faire d'utile s'il n'a pas reçu le numĂ©ro de port sur lequel le serveur attendra les paquets, ce numĂ©ro doit Ă©galement ĂȘtre connu du client. Dans ce cas, nous passons le numĂ©ro de port au constructeur de l'assistant. Le constructeur, pour sa part, exĂ©cute simplement SetAttribute avec la valeur fournie. Plus tard, si vous le souhaitez, vous pourrez dĂ©finir une autre valeur pour l'attribut « Port » Ă l'aide de SetAttribute.
Comme beaucoup d'autres objets auxiliaires, l'objet UdpEchoServerHelper a une mĂ©thode Installer. L'exĂ©cution de cette mĂ©thode conduit en fait Ă la crĂ©ation d'une application de serveur Ă©cho de base, qui est liĂ©e Ă un nĆud. Il est intĂ©ressant de noter que la mĂ©thode Installer prend NodeContainer aussi comme paramĂštre, tout comme les autres Installer mĂ©thodes que nous avons vues.
La conversion implicite en C++ qui fonctionne ici prend le rĂ©sultat de la mĂ©thode node.Get(1) (qui retourne un pointeur intelligent vers l'objet nĆud â Ptr) et l'utilise dans le constructeur pour un objet anonyme NodeContainer, qui est ensuite passĂ© Ă la mĂ©thode Installer. Si vous ne pouvez pas dĂ©terminer dans le code C++ quelle mĂ©thode avec quelle signature se compile et s'exĂ©cute, alors cherchez parmi les conversions implicites.
Maintenant, nous voyons que echoServer.Install s'apprĂȘte Ă installer l'application UdpEchoServerApplication sur le nĆud trouvĂ© dans NodeContainer, que nous utilisons pour gĂ©rer nos nĆuds, le nĆud avec l'index 1. La mĂ©thode Installer retournera le conteneur qui contient des pointeurs vers toutes les applications (dans ce cas une seule, car nous avons passĂ© un anonyme NodeContainer, contenant un nĆud) créé par l'assistant.
Les applications doivent indiquer le moment de dĂ©but de la gĂ©nĂ©ration de trafic « start » et peuvent Ă©galement avoir besoin d'indiquer le moment oĂč elle doit s'arrĂȘter « stop ». Nous fournissons les deux paramĂštres. Ces temps sont dĂ©finis Ă l'aide des mĂ©thodes ApplicationContainer Commencer et ArrĂȘter. Ces mĂ©thodes prennent des paramĂštres de type Temps. Dans ce cas, nous utilisons une sĂ©quence explicite de conversions C++ pour prendre un C++ double 1.0 et le convertir en un objet tns-3 Time, utilisant l'objet Seconds pour la conversion en secondes. N'oubliez pas que les rĂšgles de conversion peuvent ĂȘtre contrĂŽlĂ©es par l'auteur du modĂšle, et le C++ a ses propres rĂšgles, donc vous ne pouvez pas toujours vous attendre Ă ce que les paramĂštres soient convertis comme vous l'aviez prĂ©vu. Deux lignes,
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));mĂšneront Ă l'exĂ©cution de l'application d'Ă©cho serveur (s'active automatiquement) aprĂšs une seconde du dĂ©but de la simulation et s'arrĂȘte (se dĂ©sactive) aprĂšs dix secondes de simulation. Ătant donnĂ© que nous avons dĂ©clarĂ© l'Ă©vĂ©nement de simulation (l'Ă©vĂ©nement d'arrĂȘt de l'application), qui sera exĂ©cutĂ© aprĂšs dix secondes, il y aura au moins dix secondes de fonctionnement du rĂ©seau simulĂ©.
UdpEchoClientHelper
L'application cliente echo est configurée de façon pratiquement identique au serveur. Il existe un objet de base UdpEchoClientApplication, géré par
UdpEchoClientHelper.
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));Cependant, pour le client d'écho, nous devons définir cinq attributs différents. Les deux premiers attributs sont définis lors de la création UdpEchoClientHelper. Nous passons les paramÚtres qui sont utilisés (à l'intérieur de l'assistant) pour définir les attributs "RemoteAddress" et "RemotePort" conformément à notre accord sur la transmission des paramÚtres nécessaires au constructeur de l'assistant.
Rappelons que nous avons utilisĂ© Ipv4InterfaceContainer pour suivre les adresses IP que nous avons attribuĂ©es Ă nos appareils. L'interface zĂ©ro dans le conteneur d'interfaces correspondra Ă l'adresse IP du nĆud zĂ©ro dans le conteneur des nĆuds. La premiĂšre interface dans le conteneur d'interfaces correspond Ă l'adresse IP du premier nĆud dans le conteneur des nĆuds. Donc, dans la premiĂšre ligne de code (en haut), nous crĂ©ons l'assistant et lui disons que l'adresse distante du client sera l'adresse IP attribuĂ©e au nĆud oĂč se trouve le serveur. Nous indiquons Ă©galement qu'il faut organiser l'envoi des paquets au neuviĂšme port.
L'attribut «MaxPackets» informe le client du nombre maximum de paquets que nous pouvons envoyer pendant la simulation. L'attribut «Interval» indique au client combien de temps attendre entre les paquets, et l'attribut «PacketSize» indique au client la taille que doit avoir la charge utile du paquet. Grùce à cette combinaison d'attributs, nous disons au client d'envoyer un paquet de 1024 octets.
Comme dans le cas du serveur d'Ă©cho, nous dĂ©finissons les attributs pour le client d'Ă©cho Commencer et ArrĂȘter, mais ici nous lançons le client une seconde aprĂšs avoir allumĂ© le serveur (deux secondes aprĂšs le dĂ©but de la simulation).
4.2.8 Simulateur
Ă ce stade, nous devons lancer la simulation. Cela se fait Ă l'aide de la fonction globale Simulator::Run.
Simulator::Run ();Lorsque nous avons précédemment appelé les méthodes,
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
...
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));nous avons effectivement planifié des événements dans le simulateur pour 1,0 seconde, 2,0 secondes et deux événements à 10,0 secondes. AprÚs avoir appelé Simulator::Run, le systÚme commencera à parcourir la liste des événements planifiés et à les exécuter. Il commencera d'abord par l'événement prévu pour 1,0 seconde, ce qui activera l'application du serveur d'écho (cet événement peut, à son tour, planifier de nombreux autres événements). Ensuite, il lancera l'événement prévu pour t = 2,0 secondes, qui démarrera l'application du client d'écho. Encore une fois, cet événement peut planifier encore beaucoup d'autres événements. L'implémentation de l'événement de lancement dans le client d'écho commencera la phase de transfert de données de la simulation en envoyant un paquet au serveur.
L'acte d'envoyer un paquet au serveur dĂ©clenchera une chaĂźne d'Ă©vĂ©nements qui seront automatiquement planifiĂ©s en coulisses et qui mettront en Ćuvre la mĂ©canique de l'envoi de paquets d'Ă©chos en fonction des paramĂštres de synchronisation que nous avons Ă©tablis dans le scĂ©nario.
En fin de compte, comme nous n'envoyons qu'un seul paquet (rappelons que l'attribut MaxPackets Ă©tait fixĂ© Ă un), la chaĂźne d'Ă©vĂ©nements initiĂ©e par cette unique requĂȘte d'Ă©cho client se terminera, et la simulation passera en mode attente. Une fois cela fait, les Ă©vĂ©nements restants Ă traiter seront des Ă©vĂ©nements ArrĂȘter pour le serveur et le client. Lorsque ces Ă©vĂ©nements seront exĂ©cutĂ©s, il n'y aura plus d'Ă©vĂ©nements Ă traiter et Simulator::Run retournera le contrĂŽle. La simulation est terminĂ©e.
Il ne reste plus qu'Ă nettoyer. Cela se fait en appelant la fonction globale Simulator::Destroy. Ătant donnĂ© que des fonctions d'assistants (ou du code de bas niveau ns-3) ont Ă©tĂ© invoquĂ©es, qui sont organisĂ©es pour insĂ©rer des crochets dans le simulateur afin de dĂ©truire tous les objets qui ont Ă©tĂ© créés. Vous n'avez pas besoin de suivre ces objets vous-mĂȘme â tout ce que vous devez faire, c'est appeler Simulator::Destroy et sortir. Le systĂšme ns-3 fera ce travail difficile pour vous. Les lignes restantes de notre premier script ns-3, first.cc, font exactement cela :
Simulator::Destroy ();
return 0;
}Quand le simulateur s'arrĂȘtera-t-il ?
ns-3 est un simulateur d'événements discrets (DE). Dans un tel simulateur, chaque événement est lié au temps de son exécution, et la simulation se poursuit en traitant les événements dans l'ordre de leur apparition au cours de la simulation. Les événements peuvent entraßner la planification d'événements futurs (par exemple, un minuteur peut se reprogrammer pour terminer un compte à rebours dans l'intervalle suivant).
Les Ă©vĂ©nements initiaux sont gĂ©nĂ©ralement initiĂ©s par un objet, par exemple, IPv6 planifiera des services dans le rĂ©seau, des requĂȘtes de voisins, etc. L'application planifie le premier Ă©vĂ©nement d'envoi de paquet, etc. Lorsqu'un Ă©vĂ©nement est traitĂ©, il peut gĂ©nĂ©rer zĂ©ro, un ou plusieurs Ă©vĂ©nements. Ă mesure que la simulation progresse, les Ă©vĂ©nements se terminent simplement ou en gĂ©nĂšrent de nouveaux. La simulation s'arrĂȘtera automatiquement si la file d'attente des Ă©vĂ©nements est vide ou si un Ă©vĂ©nement spĂ©cial est dĂ©tectĂ© ArrĂȘter. L'Ă©vĂ©nement ArrĂȘter est gĂ©nĂ©rĂ© par la fonction Simulator::Stop (arrĂȘter le temps).
Il existe un cas typique oĂč Simulator::Stop est absolument nĂ©cessaire pour arrĂȘter la simulation : lorsque des Ă©vĂ©nements auto-sustainants sont prĂ©sents. Les Ă©vĂ©nements auto-sustainants (ou rĂ©pĂ©titifs) sont des Ă©vĂ©nements qui se reprogramment toujours. Par consĂ©quent, ils gardent toujours la file d'attente des Ă©vĂ©nements non vide. Il existe de nombreux protocoles et modules contenant des Ă©vĂ©nements rĂ©pĂ©titifs, par exemple :
âą FlowMonitor â vĂ©rification pĂ©riodique des paquets perdus ;
âą RIPng â diffusion pĂ©riodique de mises Ă jour de tables de routage ;
âą etc.
Dans de tels cas, Simulator::Stop est nĂ©cessaire pour arrĂȘter la simulation correctement. De plus, lorsque ns-3 est en mode Ă©mulation, RealTimeSimulator est utilisĂ© pour synchroniser les horloges de simulation avec les horloges de la machine, et Simulator::Stop est nĂ©cessaire pour arrĂȘter le processus.
De nombreux programmes de simulation dans le manuel ne sont pas appelĂ©s Simulator::Stop de maniĂšre explicite, car elles se terminent automatiquement lors de l'Ă©puisement des Ă©vĂ©nements dans la file d'attente. Cependant, ces programmes accepteront Ă©galement l'appel Ă Simulator::Stop. Par exemple, l'instruction supplĂ©mentaire suivante dans le premier exemple de programme planifiera un arrĂȘt explicite Ă la 11Ăšme seconde :
+ Simulator::Stop (Seconds (11.0));
Simulator::Run ();
Simulator::Destroy ();
return 0;
}Ce qui prĂ©cĂšde ne modifiera en fait pas le comportement de ce programme, car cette simulation spĂ©cifique se termine naturellement aprĂšs 10 secondes. Mais si vous deviez modifier le temps d'arrĂȘt dans l'instruction ci-dessus de 11 secondes Ă 1 seconde, vous remarqueriez que la simulation s'arrĂȘte avant que n'importe quelle sortie n'apparaisse Ă l'Ă©cran (la sortie se produisant environ 2 secondes aprĂšs le temps de simulation).
Il est important d'appeler Simulator::Stop avant d'appeler Simulator::Run ; sinon, Simulator::Run peut ne jamais rendre le contrĂŽle au programme principal pour effectuer l'arrĂȘt !
4.2.9 Assemblage de votre scénario
Nous avons rendu la création de vos scripts simples triviale. Tout ce que vous avez à faire est de placer votre script dans le répertoire scratch, et il sera automatiquement compilé lorsque vous exécuterez Waf. Essayons. Revenez au répertoire supérieur et copiez examples/tutorial/first.cc dans le répertoire scratch
$ cd ../..
$ cp examples/tutorial/first.cc scratch/myfirst.ccMaintenant, compilez votre premier exemple de script en utilisant waf:
$ ./wafVous devez voir des messages indiquant que votre premier exemple a été créé avec succÚs.
Waf : Entrée dans le répertoire `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
[614/708] cxx: scratch/myfirst.cc -> build/debug/scratch/myfirst_3.o
[706/708] cxx_link: build/debug/scratch/myfirst_3.o -> build/debug/scratch/myfirst
Waf : Sortie du répertoire `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' terminé avec succÚs (2.357s)Vous pouvez maintenant exécuter l'exemple (notez que si vous compilez votre programme dans le répertoire scratch, vous devez également l'exécuter à partir de scratch):
$ ./waf --run scratch/myfirstVous devriez voir une sortie similaire :
Waf : Entrée dans le répertoire `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf : Sortie du répertoire `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' terminé avec succÚs (0.418s) Envoyé 1024 octets à 10.1.1.2
Reçu 1024 octets de 10.1.1.1
Reçu 1024 octets de 10.1.1.2Ici, vous voyez que le systÚme de construction vérifie que le fichier a été assemblé, puis le lance. Vous constatez que l'enregistrement du client d'écho indique qu'il a envoyé un paquet de 1024 octets au serveur d'écho 10.1.1.2. Vous voyez également l'enregistrement du serveur d'écho qui indique qu'il a reçu 1024 octets de 10.1.1.1. Le serveur d'écho renvoie silencieusement le paquet, et vous voyez dans le journal du client d'écho qu'il a reçu son paquet de retour du serveur.
4.3 Code source de ns-3
Maintenant que vous avez utilisĂ© certains des assistants ns-3, vous pouvez jeter un Ćil Ă quelques codes sources qui implĂ©mentent cette fonctionnalitĂ©. Le code le plus rĂ©cent peut ĂȘtre consultĂ© sur notre serveur web Ă l'adresse suivante : . LĂ , vous verrez une page de synthĂšse Mercurial pour notre arbre de dĂ©veloppement ns-3. En haut de la page, vous verrez plusieurs liens,
summary | shortlog | changelog | graph | tags | filesAllez-y et choisissez le lien vers les fichiers. Voici à quoi ressemblera le niveau supérieur de la plupart de nos dépÎts :
drwxr-xr-x [up]
drwxr-xr-x bindings python files
drwxr-xr-x doc files
drwxr-xr-x examples files
drwxr-xr-x ns3 files
drwxr-xr-x scratch files
drwxr-xr-x src files
drwxr-xr-x utils files
-rw-r--r-- 2009-07-01 12:47 +0200 560 .hgignore file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1886 .hgtags file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1276 AUTHORS file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 30961 CHANGES.html file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 17987 LICENSE file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 3742 README file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 16171 RELEASE_NOTES file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 6 VERSION file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 88110 waf file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 28 waf.bat file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 35395 wscript file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 7673 wutils.py file | revisions | annotateNos exemples de scripts se trouvent dans le rĂ©pertoire examples. Si vous cliquez sur les exemples, vous verrez une liste de sous-rĂ©pertoires. L'un des fichiers dans le sous-rĂ©pertoire tutorial â first.cc. Si vous cliquez sur first.cc , vous verrez le code que vous venez d'Ă©tudier.
Le code source se trouve principalement dans le rĂ©pertoire src. Vous pouvez voir le code source en cliquant sur le nom du rĂ©pertoire ou en cliquant sur le lien des fichiers Ă droite du nom du rĂ©pertoire. Si vous cliquez sur le rĂ©pertoire src, vous obtiendrez une liste des sous-rĂ©pertoires src. Si vous cliquez ensuite sur le sous-rĂ©pertoire core, vous trouverez une liste de fichiers. Le premier fichier que vous verrez (au moment de la rĂ©daction de ce guide) est abort.h. Si vous cliquez sur le lien abort.h, vous serez redirigĂ© vers le fichier source pour abort.h, qui contient des macros utiles pour quitter les scripts en cas de conditions anormales. Le code source pour les helpers que nous avons utilisĂ©s dans ce chapitre peut ĂȘtre trouvĂ© dans le rĂ©pertoire src/Applications/helper. N'hĂ©sitez pas Ă explorer l'arborescence des rĂ©pertoires pour comprendre ce qui se trouve oĂč et vous familiariser avec le style de programmation de nsâ3.
Source : habr.com
