OMNeT ++ (Objective Modular Test in C ++ ) Discrete Event Simulator ist eine modulare, komponentenorientierte C ++ - Bibliothek und ein Framework fĂŒr die Modellierung diskreter Ereignisse , die hauptsĂ€chlich zum Erstellen von Netzwerksimulatoren verwendet wird . Einfach ausgedrĂŒckt handelt es sich um einen âdiskreten Ereignissimulatorâ, der Folgendes umfasst: eine IDE zum Erstellen von Modellen und den Simulator selbst (GUI).
Das INET Framework ist eine âBibliothekâ von Netzwerkmodellen fĂŒr OMNeT ++ .
Volles GIF (15,7 MiB)
In den vorherigen Teilen ...
0. Automatische Erkennung der Netzwerktopologie und nicht verwaltete Switches. Mission unmöglich? (+ klassisches Habrahabr UserCSS )
In diesem Teil:
- Erstellen Sie âIhr erstesâ Protokoll (am Beispiel von LLTR Basic).
- WĂ€hlen Sie den geeigneten Stadtsimulator zum Debuggen des Protokolls (und Erstellen des Modells).
- Wir lernen die Feinheiten des Einrichtens der Umgebung fĂŒr den Simulator und seine IDE (Konfiguration, Kompilierung, VerknĂŒpfung, Optimierung, Patching, Ignorieren veralteter Dokumentation und andere EnglĂ€nder in groĂer Zahl).
- Wir werden auf alles stoĂen, was Ihnen beim Erstellen Ihres ersten Modells Ihres ersten Protokolls in
einem unbekannten Netzwerksimulator begegnen kann. - Lass uns den ganzen Weg zusammen gehen:
- aus dem GlĂŒck, das durch die erfolgreiche (endlich!) Zusammenstellung des ersten Projekts mit einem leeren Netzwerk gebracht wurde,
- bis vollstÀndig in Experimente mit einem funktionierenden Protokollmodell eingetaucht;
- Tutorial , alles wird als Tutorial beschrieben - wir werden aus Fehlern lernen - wir werden sie machen und wir werden sie (Natur) verstehen, um elegant / effizient mit ihnen umzugehen;
- Repository (Git
), in dessen Commits und Tags alle Schritte ( "HinzufĂŒgen ..." , "Fix ..." , "Fix ..." , "Ăndern ..." , "Korrigieren ..." , ...) von Anfang bis Ende gespeichert werden.
Hinweis : ZusĂ€tzliche Informationen fĂŒr Leser des Hubs âMesh-Networkâ.
{Bildvolumen: 2,2+ (2,1) MiB; Text: 484 KiB; Emoticons: 22 StĂŒck }}
Hinweis : [Informationen zur verwendeten Partitionsstruktur] Die Struktur des Lernprogramms / Anleitungen unterscheidet sich normalerweise von der Abschnittsstruktur im Verzeichnis: Im Verzeichnis können Sie mit der Abschnittsstruktur die benötigten Informationen in einer minimalen Anzahl von Schritten erreichen (ausgeglichener Baum). In Tutorial / How-to, wo Abschnitte logisch stark miteinander verbunden sind und ein separater Abschnitt tatsĂ€chlich einer der Schritte in der Abfolge der Schritte ist, ist die Struktur eine Hierarchie von Lesezeichen (Ankern), an die Sie sich erinnern können (siehe ) ĂŒber das zuvor beschriebene Fragment.
off - topic: ĂŒber html5 <section> -Tag und Header-Tags <h #>
Es ist gut, dass das <section>
-Tag in HTML5 angezeigt wurde. Mit seiner Hilfe wurde es möglich, die Verschachtelungsebene des Abschnitts direkt festzulegen (indem die Verschachtelung der <section>
-Tags ineinander manipuliert wurde). Die Textstruktur könnte nun explizit in der Verschachtelung (Hierarchie) von Tags widergespiegelt werden.
Dies betraf auch die Header-Tags <h#>
, as Da die Verschachtelung von Abschnitten durch die Verschachtelung des <section>
, reichte es zur Angabe des Abschnittsnamens aus, nur ein <h1>
in der Form " <section><h1> </h1> </section>
" zu verwenden.
Ich habe dies schon lange verwendet (seit dem Erscheinen von <section>
), aber beim Erstellen dieses Artikels habe ich einen weiteren Vorteil der Verwendung von <section>
.
Ein guter Abschnittstitel sollte seine Essenz genau wiedergeben. Es gibt jedoch Situationen, in denen Sie die Essenz bis zur Mitte des Abschnitts beibehalten (nicht offenlegen) mĂŒssen. Das heiĂt, ein solcher Abschnitt sollte zuerst zur âRoutineâ werden und in der Mitte einen âWow / WTF-Effektâ erzeugen. Logischerweise ist dies alles - ein Abschnitt, aber wenn Sie den Namen ganz am Anfang des Abschnitts offenlegen, ist der Name selbst ein Spoiler . Stellen Sie sich ein Buch (Detektivgeschichte) vor, auf dessen Cover alle Informationen ĂŒber den âMörderâ stehen.
Hier geht das <section>
-Tag âauf die Szeneâ. Sie können den Namen des Abschnitts an einer beliebigen Stelle in sich selbst bestimmen, d. H. nicht unbedingt ganz am Anfang. Beispiel: " <section> <h1> </h1> </section>
". Es stellt sich heraus, dass wir gleichzeitig die logische Struktur des Textes speichern und den Namen des Abschnitts zum richtigen Zeitpunkt anzeigen können. Sie können den Abschnittstitel sogar visuell am Anfang anzeigen lassen, nachdem der Leser einen bestimmten Punkt erreicht hat (das <h1>
in HTML).
In etwas mehr als 9 Jahren des Bestehens von <section>
haben Browser nicht gelernt, wie man eine âHTML5-Dokumentskizzeâ richtig erstellt, um die ZugĂ€nglichkeit sicherzustellen .
Warum hast du nicht gelernt? In einem Dokument mit einer komplexen Struktur ist es schwierig * zu bestimmen, ab welchem ââTag (Abschnitt, Artikel, ...) die Nummerierung der Ăberschriften (h1, h2, h3, ...) beginnen soll. Stellen Sie sich nun vor, dass das Dokument selbst auf einer Seite wie dieser platziert wird (mit vielen zusĂ€tzlichen Blöcken, die sich nicht auf das Dokument selbst beziehen, aber Ăberschriften haben) und h1 ĂŒberall fĂŒr Ăberschriften verwendet wird. Und wenn auf einer Seite nicht ein Dokument, sondern mehrere? Optisch sieht jedoch alles gut aus ( Beispieldokument ).
* - in der Tat ist es nicht schwierig, alles ist im Standard beschrieben , aber in Wirklichkeit funktioniert es nicht (ErklÀrung siehe unten).
Warum sieht optisch alles gut aus? Hier erschienen dank der Stile zusĂ€tzliche Informationen - die Entsprechung zwischen der Abschnittshierarchie und den Kopfzeilenebenen (h #). Vielleicht sollten Sie beim Erstellen der âHTML5-Dokumentskizzeâ Informationen aus CSS verwenden? Dazu mĂŒssen Sie dem CSS-Element eine zusĂ€tzliche Eigenschaft fĂŒr das Titelelement hinzufĂŒgen, die dessen Ebene angibt, z. B.:
body>section>h2 { heading-level: 1; font-size: 1.8em; } body>section>section>h2 { heading-level: 2; font-size: 1.4em; } body>section>section>section>h2 { heading-level: 3; font-size: 1.17em; } body>section>section>section>section>h2 { heading-level: 4; font-size: 1em; } body>section>section>section>section>section>h2 { heading-level: 5; font-size: 0.83em; }
Oder eine strengere Option - in einem Abschnitt ist nur ein Header zulÀssig. In diesem Fall wird die Kopfzeilenebene durch den Abschnitt selbst festgelegt:
body>section { heading-level: 1; } body>section>section { heading-level: 2; } body>section>section>section { heading-level: 3; } body>section>section>section>section { heading-level: 4; } body>section>section>section>section>section { heading-level: 5; }
und es spielt keine Rolle, welches Header-Tag am Ende verwendet wird: h1 oder h5.
Wenn es jedoch frĂŒher ausreichte, nur eine Markierung (HTML) zu erstellen, um eine â Gliederung auf Ăberschriftenebene â zu erstellen, benötigen wir jetzt auch Stile (CSS). Vielleicht können Sie sich auf Markup (HTML) beschrĂ€nken? Mit dieser Frage sind wir dem im Standard beschriebenen Konstruktionsalgorithmus âGliederung auf Ăberschriftenebeneâ nahe gekommen. Das Problem liegt also nicht im Algorithmus selbst, sondern in der Tatsache, dass nur ein begrenzter (fester) Satz von Tags als " Schnittwurzel " -Element fungieren kann. Aber Menschen haben oft ânicht standardmĂ€Ăige WĂŒnscheâ: âIch möchte, dass das Artikel-Tag das Elementâ Schnittwurzel âauf meiner Artikellistenseite ist,â und ich möchte, dass der beliebige Abschnitt zum Element âSchnittwurzelâ wird â. Zuvor war es ausreichend, mehrere h1-Tags auf einer Seite zu verwenden (und das taten sie auch). Kann man also sicherstellen, dass jeder Abschnitt (Tags: Abschnitt, Artikel, ...) zu einem "Sectioning Root" -Element wird, wenn der Titel darin mit dem h1-Tag festgelegt wird?
# Erste Schritte: "vor dem Modellieren" / "Brainstorming"
UFO ist eingeflogen und hat diese LĂŒcke hier gelassen ? Die RĂŒckseite der Packungsbeilage aus dem vorherigen Artikel .
# Protokolldetail
Am Anfang definieren wir, was wir in das Protokoll aufnehmen mĂŒssen. Am Beispiel von LLTR Basic.
Die Basis von LLTR sind Iterationen der Statistikerfassung auf mehreren Hosts wĂ€hrend des Netzwerk-Scans. Es gibt viele Iterationen in LLTR (> 1) , daher ist das erste, was in das Protokoll aufgenommen werden muss, die Steuerung des Starts und Stopps jeder Iteration. Wenn wir berĂŒcksichtigen, dass es viele Hosts gibt (> 1) , besteht das Steuerelement darin, alle Hosts auf bestimmte Weise ĂŒber die Startzeit der Iteration und die Endzeit der Iteration zu informieren. Synchronisieren Sie also alle Hosts.
Jede Iteration hat einen eigenen Unicast-src-Host und einen eigenen Unicast-dst-Host. Als NĂ€chstes mĂŒssen Sie also die Möglichkeit haben , Unicast-src und dst fĂŒr jede Iteration zuzuweisen . Das heiĂt, in jeder Iteration sollte sich einer der Hosts als Unicast-src-Host âbewusstâ sein, dessen Zweck darin besteht, Datenverkehr an den Unicast-dst-Host zu senden.
Und der letzte. Nach Abschluss aller Iterationen mĂŒssen alle gesammelten Statistiken aller Hosts zur Verarbeitung an einen Host gesendet werden. Dieser Host analysiert die gesammelten Statistiken und erstellt die Netzwerktopologie.
In diesem Schritt können Sie auch ĂŒber einige Implementierungsdetails (EinschrĂ€nkungen) des Protokolls nachdenken. Zum Beispiel möchten wir, dass ein Programm, das LLTR verwendet, ohne Root-Rechte und aus dem Benutzerbereich (d. H. Ohne Installation eines speziellen Treibers im System) arbeiten kann, was bedeutet, dass LLTR beispielsweise ĂŒber TCP und UDP funktionieren sollte.
Alle anderen haben die Implementierung durchgefĂŒhrt und werden bei der Erstellung des Modells selbst entscheiden. Das heiĂt natĂŒrlich, Sie können sofort alles bis ins kleinste Detail durchdenken, aber gleichzeitig besteht die Gefahr, dass Sie "in ein lokales Optimum rutschen" und keine "bessere" Implementierungsoption bemerken. Es ist gut, wenn es mehrere Modelle gibt. Wenn es fĂŒr jede Implementierungsoption ein Modell gibt, können Modelle kombiniert und Schritt fĂŒr Schritt zu einer besseren Implementierung gefĂŒhrt werden. Erinnerung an den genetischen Algorithmus ïŒïŒ. Beispielsweise kann in einer Implementierung / einem Modell eine zentralisierte Verwaltung vorhanden sein, in einer anderen - dezentralisiert, in der dritten - eine Kombination der besten Teile aus den beiden vorherigen Optionen.
# Auswahl eines Netzwerksimulators
Jetzt ist es Zeit, sich fĂŒr einen Netzwerksimulator zu entscheiden, in dem wir Modelle erstellen und Experimente durchfĂŒhren.
GrundsĂ€tzlich benötigen wir von einem Netzwerksimulator die FĂ€higkeit, âunserâ Protokoll zu implementieren. Nicht alle Simulatoren machen es einfach.
Das Vorhandensein von Betriebssystememulatoren fĂŒr echte NetzwerkgerĂ€te von âWeltmarkenâ ist im Gegenteil nicht erforderlich. Höchstwahrscheinlich verursachen Emulatoren viele EinschrĂ€nkungen, die nur die Experimente beeintrĂ€chtigen.
Bei der Auswahl des Simulators halfen mir der Artikel Evaluierung von Netzwerksimulationswerkzeugen (meine Anforderungen an den Simulator stimmten in vielerlei Hinsicht ĂŒberein) und OMNeT ++ General 'Network' Simulation .
# Installieren Sie OMNeT ++ und INET
Laden Sie OMNeT ++ 5.0 herunter .
Und da OMNeT ++ nur ein âdiskreter Ereignissimulatorâ ist, benötigen Sie auch INET , eine Bibliothek von Netzwerkmodellen (Protokolle und GerĂ€te). Laden Sie INET 3.4.0 herunter . TatsĂ€chlich könnte es von der IDE installiert werden , aber ich empfehle , es manuell zu installieren (spĂ€ter wird klar, warum).
Die Installation unter * nix und unter Windows ist nicht viel anders. Ich werde am Beispiel von Windows fortfahren.
Entpacken Sie OMNeT ++ in% ProgramData% (C: \ ProgramData \) und öffnen Sie die Datei INSTALL.txt (C: \ ProgramData \ omnetpp-5.0 \ INSTALL.txt). Es heiĂt, dass sich die detaillierten Anweisungen in âdoc / InstallGuide.pdfâ befinden. Wenn Sie sie nicht lesen möchten, tun Sie einfach Folgendes:
$. setenv
$ ./configure
$ machen
Aber beeilen Sie sich nicht, es zu tun!
Achten Sie zuerst auf den ersten Befehl . setenv
â . setenv
. " Es gibt keine " setenv
" -Datei im "omnetpp-5.0" -Verzeichnis (es war in Version 5.0b1). Es wird nicht benötigt (fĂŒr Windows), fĂŒhren Sie also einfach "mingwenv.bat" aus (ich rate Ihnen, vor dem Start zu sehen, was es tut ... um rm
zu vermeiden ). Am Ende bricht das Terminal ab (neuwertig).
Zweitens rate ich Ihnen, die Datei "configure.user" ein wenig zu korrigieren (wenn der erwĂ€hnte Parameter in der Datei auskommentiert ist, mĂŒssen Sie ihn auskommentieren):
- Wenn Sie Clang (standardmĂ€Ăig) verwenden möchten, gehen Sie
PREFER_CLANG=yes
und konfigurieren:- CFLAGS_RELEASE (Compileroptionen):
CFLAGS_RELEASE='-O2 -march=native -DNDEBUG=1'
- Wenn Sie GCC anstelle von Clang verwenden möchten (und höchstwahrscheinlich GCC verwenden möchten, nachdem Sie gesehen haben, was in Zeile 398 der Datei âconfigure.inâ geschrieben steht), installieren Sie
PREFER_CLANG=no
und konfigurieren:- CFLAGS_RELEASE (Compileroptionen). Kann wÀhlen oder
CFLAGS_RELEASE='-O2 -mfpmath=sse,387 -ffast-math -fpredictive-commoning -ftree-vectorize -march=native -freorder-blocks-and-partition -pipe -DNDEBUG=1'
oder
CFLAGS_RELEASE='-O2 -fpredictive-commoning -march=native -freorder-blocks-and-partition -pipe -DNDEBUG=1'
oder
CFLAGS_RELEASE='-O2 -march=native -freorder-blocks-and-partition -pipe -DNDEBUG=1'
(befindet sich in absteigender Reihenfolge des Auftretens von Störungen). - Es lohnt sich auch, CXXFLAGS als '
-std=c++11
' + CFLAGS_RELEASE hinzuzufĂŒgen. Zum Beispiel:
CXXFLAGS='-std=c++11 -O2 -fpredictive-commoning -march=native -freorder-blocks-and-partition -pipe -DNDEBUG=1'
- JAVA_CFLAGS (nur auskommentieren):
JAVA_CFLAGS=-fno-strict-aliasing
PREFER_QTENV=yes
- Deaktivieren Sie die 3D-Visualisierung:
WITH_OSG=no
Sie ist sicherlich schön , aber wir werden es nicht brauchen. - Leider sollte auch die parallele (auf einer Reihe von CPUs) SimulationsausfĂŒhrung (WITH_PARSIM) deaktiviert werden, aber ohne sie schlĂ€gt der Linker fehl, sodass wir ihn aktiviert lassen:
WITH_PARSIM=yes
Warum sollten Sie es ausschalten?
Wenn es nicht explizit verwendet wird, wird es (theoretisch) nicht benötigt. Weitere Informationen finden Sie in den Abschnitten 16.1, 16.3 und 16.3.2 âBeispiel fĂŒr eine parallele Simulationâ in âdoc / InstallGuide.pdfâ oder hier .
Jetzt können Sie im Terminal (mintty) Folgendes tun:
./configure && make clean MODE=release make MODE=release âj17
Hinweis : " 17
" sollte durch die Anzahl der CPU + 1- Kerne oder durch 1,5 Ă Kerne ersetzt werden.
Vorsicht fĂŒr Neugierige (Build 64bit)
Das Verzeichnis "tools / win32" enthÀlt MSYS2, seine Compiler-Pakete können aktualisiert werden:
Und OMNeT ++ kann unter 64 Bit erstellt werden .
OMNeT ++ kann jedoch möglicherweise nicht mit einer neueren Version von GCC kompiliert werden (dies war bei der ersten Beta der fĂŒnften Version von OMNeT ++ der Fall - ohne Bearbeitung des Quellcodes wurde es normalerweise nur mit GCC 4.x erstellt). Und der Ăbergang zu 64-Bit erfordert noch mehr Aufwand. Zuerst mĂŒssen Sie die Kompilierungsoptionen ĂŒberprĂŒfen ( fPIC , nicht benötigt? ). Wenn Sie dann durch den OMNeT ++ - Quellcode scrollen, werden Sie feststellen , dass dort hĂ€ufig der Typ long anstelle von int32_t, size_t und ptrdiff_t (sowie uintptr_t und intptr_t) verwendet wird . Was bedroht das? In * nix in der 64-Bit-Assembly (LP64) betrĂ€gt die lange GröĂe 64-Bit und in Windows (LLP64) 32-Bit (siehe Datenmodelle ). Wir mĂŒssen long durch size_t und ptrdiff_t ersetzen, aber hier finden Sie Fallstricke. Zum Beispiel können Sie "src / utils / opp_lcg32_seedtool.cc" öffnen und in Zeile 231 - index
nachsehen oder 32 Bit verlassen (durch int32_t ersetzen) oder 64 Bit erstellen und alle Bitmasken + Beschreibungen + (möglicherweise) ein wenig Logik Ă€ndern. Daher muss ein Teil der langen Variablen 32 Bit und der andere Teil 64 Bit belassen werden. Im Allgemeinen mĂŒssen Sie fĂŒr die korrekte Operation alle Punkte ausfĂŒhren von:
Dasselbe muss mit zahlreichen Bibliotheken fĂŒr OMNeT ++ gemacht werden , zum Beispiel mit INET.
Im Allgemeinen warne ich Sie davor, eine 64-Bit- OMNeT ++ - Assembly zu erstellen.
Unter * nix empfehle ich auĂerdem die Verwendung eines 32-Bit-Builds (zumindest mit Version 5.0 und weniger).
Vielleicht wird sich Andrey2008 eines Tages verpflichten, den OMNeT ++ - und INET-Code zu ĂŒberprĂŒfen ... In der Zwischenzeit schlage ich vor, nur alle â FIXME
â / â Fix
â im ïŒïŒ -Code zu finden und FIXME
.
PS erwĂ€hnt, dass OMNeT ++ - Code , der von einem statischen Code-Analysator ĂŒberprĂŒft wurde, fehlt. In den INET 3.4.0-Dateien von âChangeLogâ finden Sie jedoch 70 ErwĂ€hnungen zum Beheben von Fehlern nach dem Scannen in Coverity.
OMNeT ++ verwendet Eclipse als IDE. Zur Vereinfachung können Sie eine VerknĂŒpfung in der IDE "% ProgramData% \ omnetpp-5.0 \ ide \ omnetpp.exe" erstellen und an einem leicht zugĂ€nglichen Ort platzieren. Das Verzeichnis "ide / jre /" enthĂ€lt JRE v1.8.0_66-b18. Wenn bereits ein kompatibles JRE / JDK im System installiert ist, kann das Verzeichnis ide / jre / sicher gelöscht werden, indem es durch einen symbolischen Link zum Speicherort des System-JRE ersetzt wird.
Beim ersten Start schlĂ€gt Eclipse vor, den Arbeitsbereich im Verzeichnis "samples" abzulegen. Es ist jedoch besser, ihn in einem anderen fĂŒr Sie geeigneten Verzeichnis auĂerhalb von "% ProgramData%" abzulegen. Die Hauptsache ist, dass im Pfad zum neuen Verzeichnis nur lateinische Buchstaben (+ Zeichen) verwendet werden und keine Leerzeichen vorhanden sind.
Nach dem SchlieĂen von Welcome bietet die IDE an, INET (wie oben beschrieben) zu installieren und die Beispiele zu importieren - verwerfen Sie beide Punkte.
Eclipse-Einstellungen, JVM-Optionen, zusÀtzliche Plugins und Themen
JVM-Optionen . FĂŒgen Sie der Datei âide / omnetpp.iniâ hinzu (jeder Editor, der LF-ZeilenvorschĂŒbe versteht, eignet sich zum Bearbeiten; der Editor funktioniert nicht), und speichert die letzte leere Zeile:
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+AggressiveOpts -XX:+TieredCompilation -XX:CompileThreshold=100
Um Eclipse wie die auf dem Bild zu machen, schauen Sie in das Bild.
Es ist Zeit, INET zu installieren. Das Verzeichnis "inet" aus dem zuvor heruntergeladenen Archiv (inet-3.4.0-src.tgz) muss in den Arbeitsbereich ĂŒbertragen werden. Im Verzeichnis befindet sich eine INSTALL-Datei mit einer schrittweisen Beschreibung der Installation. Sie können es verwenden (Abschnitt âWenn Sie die IDE verwendenâ), aber erstellen Sie einfach kein (Build-) Projekt!
INET importieren:
- Ăffnen Sie in Eclipse: Datei> Importieren.
- WĂ€hlen Sie: Allgemeine / Vorhandene Projekte im Arbeitsbereich.
- WĂ€hlen Sie als âStammverzeichnisâ den Speicherort des Arbeitsbereichs.
- Stellen Sie sicher, dass die Option "Projekte in Arbeitsbereich kopieren" deaktiviert ist.
- Warten Sie nach dem Klicken auf die SchaltflĂ€che âFertig stellenâ, bis die Indizierung des Projekts abgeschlossen ist (% der Fertigstellung, siehe unten in der Statusleiste - â C / C ++ - Indexerâ).
Richten Sie das Projekt ein:
- A. Komponenten deaktivieren, die fĂŒr LLTR nicht erforderlich sind;
- B. die Baugruppe auf Freigabe schalten;
- C. Entfernen Sie die OMNeT ++ Make Builder-Störungen (opp_makemake). FrĂŒher, als es ausgewĂ€hlt wurde, wurde das Makefile hĂ€ufig neu generiert, auch wenn es nicht erforderlich war.
- D. parallele Kompilierung aktivieren ;
- E. Optimierungen aktivieren;
- F. Aktivieren Sie die Syntaxhervorhebung fĂŒr c ++ 11 an mehreren Stellen.
- G. Beheben Sie den Fehler im Zusammenhang mit "
#include
" (dies passiert, wenn Sie "Current Builder" mehrmals Àndern; in anderen FÀllen kann dies passieren).
Bevor Sie {A} einrichten, mĂŒssen Sie eine der Projektdateien reparieren. In der Datei "inet / .oppfeatures" befindet sich eine Zeile " inet.examples.visualization
". inet.examples.visualization
mĂŒssen Sie eine leere Zeile hinzufĂŒgen, in die " inet.tutorials.visualization
" geschrieben werden soll, wobei der Einzug vorzugsweise links bleibt (analog zu anderen Parametern " nedPackages
" in der Datei ) Wenn dies nicht getan wird, passiert nichts Schlimmes. Unmittelbar nach dem Einstellen von âProblemeâ (Alt + Umschalt + Q, X) inet.tutorials.visualization
immer Fehler im Zusammenhang mit â inet.tutorials.visualization
â auf. Sie können zuerst {A} erstellen, die Fehler ĂŒberprĂŒfen und dann die Datei "inet / .oppfeatures" korrigieren. Gleichzeitig warnt Eclipse vor einer Verletzung der IntegritĂ€t in den Einstellungen und bietet an, diese zu beheben (wir stimmen dem zu).
Beginnen wir ( Fenster âProjektexplorerâ> Projekt âInetâ> KontextmenĂŒ> Eigenschaften ):
- Abschnitt OMNeT ++> Unterabschnitt Projektfunktionen
- {A} entferne alles auĂer:
- TCP Common
- TCP (INET)
- IPv4-Protokoll
- UDP-Protokoll
- Ethernet
- SchaltflĂ€che "Ăbernehmen".
- Abschnitt âC / C ++ Buildâ:
- SchaltflÀche "Konfigurationen verwalten ..."> "gcc-release" {B} aktivieren;
- WĂ€hlen Sie die Konfiguration "gcc-release [Active]" {B} .
- Unterabschnitt âTool Chain Editorâ:
- WĂ€hlen Sie als "Aktueller Builder" fĂŒr beide Konfigurationen "GNU Make Builder": "gcc-debug" und "gcc-release" {C} . Hinweis : Wenn Sie in Zukunft "Aktueller Builder" Ă€ndern, mĂŒssen Sie alles neu konfigurieren!
- SchaltflĂ€che "Ăbernehmen".
- Registerkarte "Verhalten" (kehren Sie zum Stammverzeichnis des Abschnitts "C / C ++ Build" zurĂŒck):
- Setzen Sie "Parallele Jobs verwenden" auf N (entweder N ist die Anzahl der CPU- Kerne + 1 oder 1,5 Ă Kerne) - damit können alle CPU-Kerne zum Kompilieren von {D} verwendet werden (konfigurieren Sie fĂŒr "gcc-debug" und "gcc-"). Release â).
- Registerkarte "Build-Einstellungen":
- Deaktivieren Sie "Standard-Build-Befehl verwenden".
- Ersetzen Sie die Zeile "Build command" durch "
make MODE=release CONFIGNAME=${ConfigName} -j17
" (ersetzen Sie " 17
" durch den vorherigen Wert in der Zeile, dh durch das ausgewĂ€hlte N) {E} . Sie können dasselbe tun Ersetzen Sie fĂŒr die Konfiguration "gcc-debug" " MODE=release
" durch " MODE=debug
" in der Zeile. Vergessen Sie danach nicht, wieder zu "gcc-release [Active]" zu wechseln.
- SchaltflĂ€che "Ăbernehmen".
- Abschnitt âC / C ++ Allgemeinâ:
- Unterabschnitt âPfade und Symboleâ:
- Registerkarte "Beinhaltet":
- SchaltflÀche "
../src
": FĂŒgen Sie das Verzeichnis " ../src
" mit den ausgewÀhlten ../src
"Zu allen Konfigurationen hinzufĂŒgen" und "Zu allen Sprachen ../src
" {G} hinzu. Anfangs ist " ../src
" in der Sprache "GNU C ++ ", jedoch zu einem ungewissen Zeitpunkt kann es aus der Liste gelöscht werden; ../src
Sie auf die SchaltflĂ€che â ../src
â und ĂŒberprĂŒfen Sie, ob â ../src
â in allen Sprachen und Konfigurationen ../src
.
- Registerkarte "Symbole":
- SchaltflÀche "
__cplusplus
": FĂŒgen Sie das Symbol " __cplusplus
" mit dem Wert " 201103L
" und den ausgewÀhlten 201103L
"Zu allen Konfigurationen hinzufĂŒgen" und "Zu allen Sprachen hinzufĂŒgen" __cplusplus
- {F} more ; __cplusplus
die 201103L
" 201103L
" und ĂŒberprĂŒfen Sie, __cplusplus
" __cplusplus
" in der Konfiguration "gcc-debug" den Wert " 201103L
" hat.
- Registerkarte "Quellspeicherort":
- ĂberprĂŒfen Sie, ob ein Element in der Liste vorhanden ist und auf "
/inet/src
" {G} zeigt. Wenn noch etwas vorhanden ist (z. B. " /inet
"), löschen Sie das Element und fĂŒgen Sie es hinzu ("Ordner hinzufĂŒgen") ... â)â /inet/src
â. Klicken Sie dann auf die SchaltflĂ€che âĂbernehmenâ und kehren Sie zu {A} zurĂŒck , weil Alle Filter wurden beim Löschen gelöscht. Ăbrigens kann " /inet
" tatsĂ€chlich belassen werden - alles lĂ€uft auch gut, aber es ist besser, es auf das ursprĂŒngliche " /inet/src
" zu beschrÀnken.
- Unterabschnitt âPrĂ€prozessor enthĂ€lt Pfade, Marcos usw.â > Registerkarte "Anbieter":
- WĂ€hlen Sie "CDT GCC Build-in Compiler-Einstellungen":
- Klicken Sie in der Gruppe "Anbieteroptionen fĂŒr Spracheinstellungen" auf den Link "Arbeitsbereichseinstellungen":
- Registerkarte "Discovery":
-std=c++11
erneut "CDT GCC Build-in Compiler Settings" und fĂŒgen Sie " -std=c++11
" vor " ${FLAGS}
" in "Befehl zum ${FLAGS}
Compilerspezifikationen" hinzu. Es sollte ${FLAGS}
so aussehen wie " ${COMMAND} -std=c++11 ${FLAGS} -E -P -v -dD "${INPUTS}"
` {F} , weitere Details hier und hier ; - SchaltflĂ€che "Ăbernehmen", "Ok" (Fenster schlieĂen).
- Verschieben Sie "CDT GCC Build-in Compiler-Einstellungen" ĂŒber "CDT Managed Build System Entries" (fĂŒr beide Konfigurationen: "gcc-release" und "gcc-debug") {F} , weitere Details - danach verlieren wir die Möglichkeit, die Zeichen "CDT" neu zu definieren GCC Build-in Compiler-Einstellungen âĂŒberâ CDT Managed Build System-EintrĂ€ge â( â C / C ++ Allgemein â> â Pfade und Symbole â> â Symbole â) können Sie nur ĂŒberschreiben, indem Sie denâ CDT-BenutzereinstellungseintrĂ€gen âWerte hinzufĂŒgen. âEntriesâ (: , .. âCDT Managed Build System Entriesâ â
__cplusplus
â; , â __cplusplus
__cplusplus
â âCDT Managed Build System Entriesâ, , ); - âApplyâ, , âEntriesâ âGNU C++ â âCDT GCC Build-in Compiler Settingsâ ( [ ] âShow build-in valuesâ ) â
__cplusplus=201103L
â ( ).
- âIndexerâ:
- âBuild configuration for indexerâ âgcc-releaseâ {B} ;
- âApplyâ.
{E} . Ich werde es erklĂ€ren. , Eclipse , âconfigure.userâ OMNeT++ (./configure). Eclipse g++ make. , , , . , âBuild commandâ {E} â --just-print
â â --trace
â, , ( âProject Explorerâ > âinetâ > > âClean Projectâ âBuild Projectâ), âConsoleâ (Alt+Shift+Q,C), â â g++ -c -std=c++11 -O2 -fpredictive-commoning -march=native -freorder-blocks-and-partition -pipe -DNDEBUG=1 âŠ
â. , .
( âProject Explorerâ > âinetâ > > Properties ):
- â/++ Buildâ:
- âBuild Variablesâ (, âgcc-release [ Active ]â):
- âAddâŠâ, â
CFLAGS
â, âStringâ, â -O2 -fpredictive-commoning -march=native -freorder-blocks-and-partition -pipe
â; - âAddâŠâ, â
CXXFLAGS
â, âStringâ, â -std=c++11 -O2 -fpredictive-commoning -march=native -freorder-blocks-and-partition -pipe
â; - âApplyâ.
- âEnvironmentâ:
- âAddâŠâ, â
CFLAGS
â, â ${CFLAGS}
â; - âAddâŠâ, â
CXXFLAGS
â, â ${CXXFLAGS}
â; - âApplyâ.
, , g++ , â --just-print
â â --trace
â, Process Explorer . Process Explorer , â -march=native
â âcc1plus.exeâ.
, , INET! , âgcc-releaseâ {B} , â --just-print
â â --trace
â {E} , . ( âProject Explorerâ > âinetâ > > âClean Projectâ âBuild Projectâ), âConsoleâ (Alt+Shift+Q,C).
, Eclipse, â.cprojectâ â.settingsâ {BG} , : â.oppfeaturesâ, â.oppfeaturestateâ, â.nedexclusionsâ â {A} .
, , .
Note : , â âdocâ OMNeT++ INET. Simulation Manual User Guide, Stack Overflow ( stackoverflow.com, ). , , , , ââ .
Note : , OMNeT++ INET, , INET GitHub. 3.4.0 ( , INET ).
INET, , . , ?
INET âProject Explorerâ, âinet/src/inet/applicationsâ, â udpapp â (UDP Application). UDP broadcast . , , , , â UDPEchoApp â. âUDPBasicAppâ, âBasicâ. â.ccâ, â.hâ â.nedâ . , â.nedâ , ( âparameters:
â ) .
. , ( inet/examples ) INET. , âbroadcastâ ( inet/examples/inet/broadcast )! â.ccâ, â.hâ â.nedâ, â.iniâ â.xmlâ . , :
, (âbroadcastâ) , .. . , , .
Note : Simulation Manual . , , ( RAM) . JS â bookmark let . , Simulation Manual, ( ), ( target
Simulation Manual). Bookmarklet . , , Simulation Manual , bookmarklet .
bookmarklet , ?
bookmarklet . . 5- . bookmarklet , .
â bookmarklet â ; bookmarklet , ( 5- ) â .
âLLTRâ, âsrcâ âsimulationsâ, âgcc-releaseâ (File â New â OMNeT++ ProjectâŠ):
âinetâ, . , âgcc-debugâ (.. âLLTRâ), âinetâ. : {A,B,G} âProject Referencesâ, âinetâ.
, Wizard, , âpackage.nedâ : âsrcâ, âsimulationsâ. â â package lltr;
â â package lltr.simulations;
â . .
INET, âinet/srcâ â âLLTR/srcâ, âinet/examplesâ â âLLTR/simulationsâ. âLLTR/simulationsâ â.nedâ c Network , âLLTR/srcâ â ().
â INET , INET, , INET. , â INET.
, â.nedâ âLLTR/srcâ ( âinet/srcâ), â package lltr.simulations;
â âLLTR/simulationsâ. âpackage.nedâ âLLTR/srcâ âLLTR/simulationsâ.
LLTR. âLLTR/simulations/omnetpp.iniâ, ( Run > Run As > 1 OMNeT++ Simulation):
Eclipse âsimulationsâ . , : âLLTR/src/LLTR.exeâ . , âLLTR.exeâ , ( Project â Build Project), ( ).
âNo network specified in the configuration.â, , â network = lltr. Network
â â [General]
â âomnetpp .ini â, â network Network {}
â âpackage .ned â. ( â.nedâ ), ( â.iniâ ) ( Network â ) .
( Run > Run As > 1 OMNeT++ Simulation), () Network .
Note : ( Run > Run As > 1 OMNeT++ Simulation), ( Run > 1 simulations): , .. , , Eclipse .
Note : ( â a1_v0.1.0 (âaâ â article) â git checkout -b âčmy_branchâș tags/a1_v0.1.0
â) 
, :
- tutorial git;
- tutorial â ;
- () , (article) â ( : âarticle_#â), / ;
- , ââ tutorial.
Note : âarticle_#â , , , ( ), /.
â â? , GitHub , :
, , â git checkout -b âč my_branch âș tags/âčtag_nameâș
â.
, .. ? Pull Request, >:-), , , , ):
, , Pull Request .
Note : , : , ( â â () , ). â -u â , . , âa1_v0.1. 0 â, âa1_v0.2. 0 â, ⊠â âa1_v0.1. 1 â, âa1_v0.2. 1 â, ⊠, : âa1_v0.1. 2 â, âa1_v0.2. 2 â, âŠ
Note : tutorial , ââ, git
, git tag.
Note : git diff , , ( , / ) ( AST ), Java .
# (Link Layer Topology Reveal)
# â1:
âpackage.nedâ ( âDesignâ ), :
, broadcast :
- â StandardHost;
- â EtherSwitch.
ââ ( ) Eth100M (: 100 Mbps; : 10 ). , 10 , , ? ( )
( âSourceâ ), (git tag a1_v0.2.0)
. :
package âč<a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-ref:packages"> </a>âș;
Warning : <a>...</a>
â ââ . , , , ( <strong>...</strong>
, <em>...</em>
).
package âč âș; //
import âč âș;
network âč âș
{
@display(âč , , âș);
submodules :
âč âș: âč âș { @display(âč , , âș); }
connections :
âč âș.âč âș <--> âč âș <--> âč âș.âč âș;
}
â â (Gates) :
- Gates , , gate â
âč âș.âčgateâș[âčâș]
â, â â âč âș.âčgateâș ++
â. - (: â
⊠<--> { delay = 100ms; } <--> âŠ
â), / , ( broadcast : â ⊠<--> C <--> âŠ
â), (: â ⊠<--> FastEthernet {per = 1e-6;} <--> âŠ
â), ⊠- Gates ( :
output
/ input
; : -->
/ <--
), ( : inout
; : <-->
). , , â $i
â â $o
â .
Warning : 1 â 3 20 ( 504 âGateway Time-outâ). 1 â 3 . ( ):
<a href="#set">: â<code>set: p=1.87548</code>â</a> .
:
<a href="#set"><code>: âset: p=1.87548</code>â</a> .
, 3â . :
, <a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-ref:inout-gates"> â<strong><code>$i</code></strong>â â<strong><code>$o</code></strong>â</a>.
, . , , GitHub Pages:

Note : target
Simulation Manual â bookmarklet ', . « â» , .
Note : , CSS JS â , 3 , GitHub Pages 2â ( HTML, , , , â). 3â â .
# / To be continuedâŠ
- 2.
- 3. OMNeT++
- 4.
- 5. OMNeT++ 2
- 6.
- 7. (â: â â)

. . â . â .