LLTR Parte 1: Primeros pasos en OMNeT ++ e INET

OMNeT ++ (Objective M odular N etwork Testbed in C ++ ) Discrete Event Simulator es una biblioteca modular C ++ orientada a componentes y un marco para el modelado de eventos discretos , utilizado principalmente para crear simuladores de red . En pocas palabras, este es un "simulador de eventos discretos", que incluye: un IDE para crear modelos y el simulador en sí (GUI).


INET Framework es una "biblioteca" de modelos de red para OMNeT ++ .


KDPV: LLTR Parte 1 - OMNeT ++ 5 the Open Simulator :: Modelo LLTR :: para uso libre


GIF completo (15.7 MiB)


En las partes anteriores ...


0. Detección automática de topología de red y conmutadores no administrados. Misión imposible? (+ clásico Habrahabr UserCSS )


En esta parte:


  • cree "su primer" protocolo (usando LLTR Basic como ejemplo);
  • elija el simulador de ciudad apropiado para depurar el protocolo (y crear su modelo);
  • aprendemos las sutilezas de configurar el entorno para el simulador y su IDE (configuración, compilación, vinculación, ajuste, parcheo, ignorar documentación obsoleta y otros inglesismos en grandes cantidades);
  • encontraremos todo lo que podamos encontrar al crear nuestro primer modelo de nuestro primer protocolo en un simulador de red desconocido;
  • vamos todos juntos:
    • de la felicidad que trajo la compilación exitosa (¡por fin!) del primer proyecto con una red vacía,
    • hasta estar completamente inmerso en experimentos con un modelo de protocolo en funcionamiento;
  • tutorial , todo se describe como tutorial : aprenderemos de los errores, los cometeremos y los entenderemos (la naturaleza) para tratarlos de manera elegante / eficiente;
  • repositorio (git ), en las confirmaciones y etiquetas de las que se guardan todos los pasos ( "Agregar ..." , "Reparar ..." , "Reparar ..." , "Modificar ..." , "Corregir ..." , ...), de principio a fin.


Nota : información adicional para lectores del centro "Mesh-network".


{volumen de imágenes: 2.2+ (2.1) MiB; Texto: 484 KiB; Emoticones: 22 piezas }


Nota : [sobre la estructura de partición utilizada] la estructura de las secciones de tutorial / procedimientos suele ser diferente de la estructura de sección en el directorio: en el directorio, la estructura de sección le permite llegar a la información que necesita en un número mínimo de pasos (árbol equilibrado); en el tutorial / cómo, donde las secciones están fuertemente conectadas lógicamente, y una sección separada, de hecho, es uno de los pasos en la secuencia de pasos, la estructura es una jerarquía de marcadores (anclas), que le permite recordar (consulte ) sobre el fragmento descrito anteriormente.


off - topic: acerca de la etiqueta html5 <section> y las etiquetas de encabezado <h #>

Es bueno que la etiqueta <section> apareciera en HTML5, con su ayuda fue posible establecer directamente el nivel de anidamiento de la sección (manipulando el anidamiento de las etiquetas <section> entre sí). La estructura del texto ahora podría reflejarse explícitamente en la anidación (jerarquía) de las etiquetas.


Esto también afectó a las etiquetas de encabezado <h#> , como Dado que el anidamiento de secciones está determinado por el anidamiento de la <section> , para indicar el nombre de la sección, fue suficiente usar solo una <h1> en la forma: " <section><h1> </h1> </section> ".


He estado usando esto durante mucho tiempo (desde la aparición de <section> ), pero al crear este artículo, vi otra ventaja de usar <section> .


Un buen título de sección debe reflejar con precisión su esencia, sin embargo, hay momentos en los que necesita mantener (no revelar) la esencia hasta la mitad de la sección. Es decir, dicha sección primero debe convertirse en "rutina", y en el medio crear un "efecto wow / wtf". Lógicamente, esta es toda una sección, pero si revela su nombre al comienzo de la sección, entonces el nombre en sí será un spoiler . Imagine un libro (historia de detectives), en la portada de la cual encontrará toda la información sobre el "asesino".


Aquí es donde la etiqueta <section> "entra en escena". Le permite determinar el nombre de la sección en cualquier lugar dentro de usted, es decir. no necesariamente al principio. Ejemplo: “ <section> <h1> </h1> </section> ". Resulta que podemos guardar simultáneamente la estructura lógica del texto y mostrar el nombre de la sección en el momento adecuado. Incluso puede hacer que el título de la sección aparezca visualmente al principio, después de que el lector llegue a cierto punto (la <h1> en html).


En poco más de 9 años de la existencia de <section> , los navegadores no han aprendido cómo construir adecuadamente un "esquema de documento HTML5" para garantizar la accesibilidad .


¿Por qué no aprendiste? En un documento con una estructura compleja, es difícil * determinar desde qué etiqueta (sección, artículo, ...) debe comenzar la numeración de los encabezados (h1, h2, h3, ...). Ahora imagine que el documento en sí se coloca en una página como esta (con muchos bloques adicionales que no están relacionados con el documento en sí, pero tienen encabezados), y h1 se usa en todas partes para los encabezados. ¿Y si en una página no es un documento, sino varios? Sin embargo, visualmente todo se ve bien ( documento de ejemplo ).


* - de hecho no es difícil, todo se describe en el estándar , pero en realidad no funciona (ver explicación más abajo).


¿Por qué todo se ve bien visualmente? Aquí, gracias a los estilos , apareció información adicional: la correspondencia entre la jerarquía de secciones y los niveles de encabezado (h #). Entonces, ¿al construir el "esquema del documento HTML5" debería usar la información de CSS? Para hacer esto, debe agregar una propiedad adicional al elemento CSS para el elemento de título que indica su nivel, por ejemplo:


 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; } 


O una opción más rigurosa: solo se permite un encabezado en una sección. En este caso, el nivel del encabezado lo establece la sección misma:


 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; } 


, y no importa qué etiqueta de encabezado se utilizará al final: h1 o h5.


Sin embargo, si antes para crear un " esquema de nivel de encabezado " era suficiente tener solo marcado (HTML), ahora también necesitamos estilos (CSS). ¿Quizás puede limitarse solo a marcado (HTML)? Con esta pregunta, nos hemos acercado al problema del algoritmo de construcción de "esquema de nivel de encabezado" descrito en el estándar. Por lo tanto, el problema no está en el algoritmo en sí, sino en el hecho de que solo un conjunto limitado (fijo) de etiquetas puede actuar como un elemento de " raíz seccionadora ". Pero las personas a menudo tienen "deseos no estándar": "Quiero que la etiqueta del artículo sea el elemento 'raíz de seccionamiento'" en mi página de lista de artículos, "y quiero que la sección arbitraria se convierta en el elemento 'raíz de seccionamiento'". Anteriormente, era suficiente para ellos usar varias etiquetas h1 en una página (y lo hicieron). Entonces, ¿puede asegurarse de que cualquier sección (etiquetas: sección, artículo, ...) se convierta en un elemento de "raíz seccionadora" si el título se configura con la etiqueta h1? ..



# Primeros pasos: "antes de modelar" / "lluvia de ideas"


Folleto

¿Ovni voló y dejó esta brecha aquí ? El reverso del folleto del artículo anterior .


# Detalle del protocolo


Al principio definimos lo que necesitamos incluir en el protocolo. En el ejemplo de LLTR Basic.


La base de LLTR son las iteraciones de la recopilación de estadísticas en varios hosts durante la exploración de la red. Hay muchas iteraciones en LLTR (> 1) , por lo que lo primero que se debe incluir en el protocolo es controlar el inicio y la detención de cada iteración. Si tenemos en cuenta que hay muchos hosts (> 1) , el control consistirá en informar a todos los hosts de una determinada manera la hora de inicio de la iteración y la hora de finalización de la iteración. Es decir, sincronizar todos los hosts.


Cada iteración tiene su propio host src de unidifusión y host dst de unidifusión, por lo que lo siguiente que debe habilitar es la forma de asignar src y dst de unidifusión para cada iteración. Es decir, en cada iteración, uno de los hosts debe "ser consciente" de sí mismo como un host src de unidifusión, cuyo propósito es enviar tráfico al host dst de unidifusión.


Y el último. Al finalizar todas las iteraciones, todas las estadísticas recopiladas de todos los hosts deben enviarse a un host para su procesamiento. Este host analizará las estadísticas recopiladas y creará la topología de la red.


Además, en este paso, puede pensar en algunos detalles de implementación (limitaciones) del protocolo. Por ejemplo, queremos que un programa que use LLTR pueda funcionar sin derechos de root y desde el espacio del usuario (es decir, sin instalar un controlador especial en el sistema), lo que significa que LLTR debería funcionar, por ejemplo, a través de TCP y UDP.


Todos los demás hicieron la implementación, decidirán por sí mismos en el proceso de creación del modelo. Es decir, por supuesto, puede pensar inmediatamente en todo hasta el más mínimo detalle, pero al mismo tiempo existe el riesgo de "caer en un óptimo local" y no notar una opción de implementación "mejor". Es bueno cuando haya varios modelos: si hay un modelo para cada opción de implementación, entonces será posible combinar modelos y, paso a paso, llegar a una mejor implementación. Recordando el algoritmo genético ;). Por ejemplo, en una implementación / modelo puede haber una administración centralizada, en otra, descentralizada, en la tercera, una combinación de las mejores partes de las dos opciones anteriores.


# Elegir un simulador de red


Ahora es el momento de decidir un simulador de red en el que crearemos modelos y configuraremos experimentos.


Básicamente, desde un simulador de red, necesitamos la capacidad de implementar "nuestro" protocolo. No todos los simuladores lo hacen fácil.


Pero, por el contrario, no es necesaria la presencia de emuladores del sistema operativo de equipos de red reales de "marcas mundiales". Lo más probable es que los emuladores creen muchas limitaciones que solo interferirán con los experimentos.


Con la elección del simulador, el artículo Evaluación de herramientas de simulación de red (mis requisitos para el simulador coincidieron en muchos aspectos) y OMNeT ++ General 'Network' Simulation me ayudó.


# Instalar OMNeT ++ e INET


Descargar OMNeT ++ 5.0 .


Y dado que OMNeT ++ es solo un "simulador de eventos discretos", también necesitará INET , una biblioteca de modelos de red (protocolos y dispositivos). Descargar INET 3.4.0 . De hecho, podría instalarse desde el IDE , pero recomiendo instalarlo manualmente (más adelante quedará claro por qué).


La instalación en * nix y en Windows no es muy diferente. Continuaré con el ejemplo de Windows.


Descomprima OMNeT ++ en% ProgramData% (C: \ ProgramData \) y abra el archivo INSTALL.txt (C: \ ProgramData \ omnetpp-5.0 \ INSTALL.txt). Dice que las instrucciones detalladas están en "doc / InstallGuide.pdf", además está escrito que si no desea leerlo, simplemente haga lo siguiente:

$. setenv
$ ./configure
$ make

¡Pero no te apresures a hacerlo!


Primero, presta atención al primer comando . setenv . setenv ". No hay un archivo " setenv " en el directorio "omnetpp-5.0" (estaba en la versión 5.0b1). No es necesario (para Windows), así que simplemente ejecute "mingwenv.bat" (le aconsejo que vea lo que hace antes de comenzar ... para evitar el rm ). Al final, la terminal se interrumpirá (mintty).


En segundo lugar, le aconsejo que corrija un poco el archivo "configure.user" (si el parámetro mencionado está comentado en el archivo, entonces debe descomentarlo):


  • Si quieres usar Clang (por defecto), deja
    PREFER_CLANG=yes
    y configurar:
    • CFLAGS_RELEASE (opciones del compilador):
      CFLAGS_RELEASE='-O2 -march=native -DNDEBUG=1'
  • Si desea usar GCC en lugar de Clang (y probablemente quiera usar GCC después de ver lo que está escrito en la línea 398 del archivo "configure.in"), instale
    PREFER_CLANG=no
    y configurar:
    • CFLAGS_RELEASE (opciones del compilador). Puede elegir o
      CFLAGS_RELEASE='-O2 -mfpmath=sse,387 -ffast-math -fpredictive-commoning -ftree-vectorize -march=native -freorder-blocks-and-partition -pipe -DNDEBUG=1'
      o
      CFLAGS_RELEASE='-O2 -fpredictive-commoning -march=native -freorder-blocks-and-partition -pipe -DNDEBUG=1'
      o
      CFLAGS_RELEASE='-O2 -march=native -freorder-blocks-and-partition -pipe -DNDEBUG=1'
      (ubicado en orden decreciente de aparición de problemas técnicos).
    • También vale la pena agregar CXXFLAGS como ' -std=c++11 ' + CFLAGS_RELEASE. Por ejemplo:
      CXXFLAGS='-std=c++11 -O2 -fpredictive-commoning -march=native -freorder-blocks-and-partition -pipe -DNDEBUG=1'
    • JAVA_CFLAGS (solo descomentar):
      JAVA_CFLAGS=-fno-strict-aliasing
  • PREFER_QTENV=yes
  • Desactiva la visualización en 3D:
    WITH_OSG=no
    Ella es ciertamente hermosa , pero no la necesitaremos.
  • Desafortunadamente, la ejecución de la simulación paralela (en un conjunto de CPU) (WITH_PARSIM) también debe desactivarse, pero sin que falle el enlazador, lo dejaremos activado:
    WITH_PARSIM=yes

¿Por qué deberías apagarlo?

Si no se usa explícitamente, entonces no es necesario (en teoría). Más detalles en las secciones 16.1, 16.3 y 16.3.2 "Ejemplo de simulación paralela" en "doc / InstallGuide.pdf", o aquí .



Ahora en la terminal (mintty) puedes hacer:


 ./configure && make clean MODE=release make MODE=release –j17 


Nota : " 17 " debe ser reemplazado por el número de núcleos de CPU + 1 , o por 1.5 × núcleos.


Precaución para los curiosos (compilación de 64 bits)

El directorio "tools / win32" contiene MSYS2, sus paquetes de compilación se pueden actualizar:



Y OMNeT ++ se puede construir bajo 64 bits .


Pero OMNeT ++ simplemente no puede compilarse con una versión más nueva de GCC (este fue el caso con la primera versión beta de la quinta versión de OMNeT ++ ; sin editar el código fuente, normalmente se creó solo con GCC 4.x). Y la transición a 64 bits requerirá aún más esfuerzo. Primero debe revisar las opciones de compilación ( fPIC , ¿ no es necesario? ). Luego, si se desplaza por el código fuente OMNeT ++ , verá que el tipo largo a menudo se usa allí en lugar de int32_t, size_t y ptrdiff_t (así como uintptr_t e intptr_t) . ¿Qué amenaza esto? En * nix en el ensamblaje de 64 bits (LP64), el tamaño largo será de 64 bits, y en Windows (LLP64) será de 32 bits (ver modelos de datos ). Tendremos que reemplazar long por size_t y ptrdiff_t, pero aquí encontrará dificultades. Por ejemplo, puede abrir "src / utils / opp_lcg32_seedtool.cc" y mirar la línea 231 - index o puede dejar 32 bits (reemplazar con int32_t), o hacer 64 bits y modificar todas las máscaras de bits + descripciones + (posiblemente) un poco de lógica. Por lo tanto, una parte de las variables largas deberá dejarse 32 bits, y la otra parte será de 64 bits. En general, para la operación correcta, debe hacer todos los puntos desde:



Y lo mismo debe hacerse con numerosas bibliotecas para OMNeT ++ , por ejemplo, con INET.


En general, le advierto que no intente construir un ensamblado OMNeT ++ de 64 bits.


En * nix, también recomiendo usar una compilación de 32 bits (al menos con la versión 5.0 y menos).


Quizás algún día Andrey2008 se comprometerá a verificar el código OMNeT ++ y el código INET ... Mientras tanto, sugiero encontrar y ver todos los " FIXME " / " Fix " en el código ;).


PS menciona que el código OMNeT ++ fue verificado por un analizador de código estático que falta, pero en los archivos "ChangeLog" INET 3.4.0 puede encontrar 70 menciones sobre la reparación de defectos después de escanear en Coverity.



OMNeT ++ usa Eclipse como IDE. Para mayor comodidad, puede crear un acceso directo en el IDE "% ProgramData% \ omnetpp-5.0 \ ide \ omnetpp.exe" y colocarlo en un lugar de fácil acceso. El directorio "ide / jre /" contiene JRE v1.8.0_66-b18. Si ya hay un JRE / JDK compatible instalado en el sistema, entonces el directorio ide / jre / se puede eliminar de forma segura reemplazándolo por un enlace simbólico a la ubicación del JRE del sistema.


Al principio, Eclipse sugiere colocar el espacio de trabajo en el directorio "samples", sin embargo, es mejor colocarlo en cualquier otro directorio conveniente para usted fuera de "% ProgramData%". Lo principal es que solo se usan letras latinas (+ caracteres) en la ruta al nuevo directorio, y no hay espacios.


Después de cerrar Bienvenido, el IDE ofrecerá instalar INET (como se describió anteriormente) e importar los ejemplos: descarte ambos puntos.


Configuración de Eclipse, opciones de JVM, complementos y temas adicionales

Opciones de JVM . Agregue "ide / omnetpp.ini" al archivo (cualquier editor que entienda los avances de línea LF es adecuado para editar; el bloc de notas no funcionará), guardando la última línea vacía:


 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+AggressiveOpts -XX:+TieredCompilation -XX:CompileThreshold=100 

Eclipse tuning (un [7z] me)


Para hacer Eclipse como el de la imagen, mire dentro de la imagen.



Es hora de instalar INET. El directorio "inet" del archivo descargado previamente (inet-3.4.0-src.tgz) debe transferirse al espacio de trabajo. Hay un archivo "INSTALAR" en el directorio con una descripción paso a paso de la instalación. Puede usarlo (sección "Si está usando el IDE"), ¡pero no cree un proyecto (Build)!


Importar INET:


  1. En Eclipse, abra: Archivo> Importar.
  2. Seleccione: Proyectos generales / existentes en el espacio de trabajo.
  3. Como el "directorio raíz", seleccione la ubicación del espacio de trabajo.
  4. Asegúrese de que la opción "Copiar proyectos en el espacio de trabajo" esté desactivada.
  5. Después de hacer clic en el botón "Finalizar", espere hasta que se complete la indexación del proyecto (% de finalización, ver más abajo, en la barra de estado - " C / C ++ Indexer").


Configurar el proyecto:


  • A. desactivar componentes innecesarios para LLTR;
  • B. cambiar el conjunto para liberar;
  • C. deshacerse de los fallos de OMNeT ++ Make Builder (opp_makemake): anteriormente, cuando se seleccionaba, el Makefile a menudo se regeneraba, incluso cuando no era necesario;
  • D. permitir la compilación paralela ;
  • E. activar optimizaciones;
  • F. active el resaltado de sintaxis para c ++ 11 , en varios lugares;
  • G. corrija el error relacionado con " #include " (sucede si cambia "Current builder" varias veces; puede ocurrir en otros casos).


Antes de configurar {A}, debe corregir uno de los archivos del proyecto. En el archivo "inet / .oppfeatures" hay una línea " inet.examples.visualization " necesita agregar una línea vacía después de ella para escribir " inet.tutorials.visualization ", preferiblemente manteniendo la sangría a la izquierda (por analogía con otros parámetros " nedPackages " en el archivo ) Si no se hace esto, no sucederá nada malo, justo después de configurar "Problemas" (Alt + Shift + Q, X) siempre habrá errores asociados con " inet.tutorials.visualization ". Primero puede hacer {A} , y mirar los errores, y luego corregir el archivo "inet / .oppfeatures" - al mismo tiempo, Eclipse advertirá sobre la violación de la integridad en la configuración y ofrecerá corregirlos (estamos de acuerdo con esto).


Comencemos (panel "Explorador de proyectos"> proyecto "inet"> menú contextual> Propiedades ):


  1. Sección OMNeT ++> Subsección de características del proyecto
    1. {A} eliminar todo excepto:
      • TCP común
      • TCP (INET)
      • Protocolo IPv4
      • Protocolo UDP
      • Ethernet
    2. Botón "Aplicar".
  2. Sección "C / C ++ Build":
    1. Botón "Administrar configuraciones ..."> active "gcc-release" {B} ;
    2. seleccione la configuración "gcc-release [Active]" {B} .
    3. Subsección "Editor de cadena de herramientas":
      1. como "Generador actual" seleccione "GNU Make Builder" para ambas configuraciones: "gcc-debug" y "gcc-release" {C} , nota : si cambia "Current builder" en el futuro, ¡tendrá que volver a configurar todo!
      2. Botón "Aplicar".
    4. Pestaña "Comportamiento" (regrese a la raíz de la sección "Compilación C / C ++"):
      1. establezca "Usar trabajos paralelos" en N (N es el número de núcleos de CPU + 1 o 1,5 × núcleos); esto permitirá que todos los núcleos de CPU se utilicen para compilar {D} (configurar para "gcc-debug" y "gcc- liberar ").
    5. Ficha Configuración de compilación:
      1. deshabilite "Usar el comando de compilación predeterminado";
      2. reemplace la línea "Comando de compilación" con " make MODE=release CONFIGNAME=${ConfigName} -j17 " (reemplace " 17 " con el valor anterior en la línea, es decir, con el N seleccionado {E} , puede hacer lo mismo para la configuración "gcc-debug", reemplazando " MODE=release " con " MODE=debug " en la línea, después de eso no olvide volver a "gcc-release [Active]".
    6. Botón "Aplicar".
  3. Sección "C / C ++ General":
    1. Subsección "Caminos y símbolos":
      1. Pestaña "Incluye":
        1. Botón Agregar: agregue el directorio " ../src " con el "Agregar a todas las configuraciones" y "Agregar a todos los idiomas" {G} seleccionados - inicialmente " ../src " está en el idioma "GNU C ++ ", pero en un momento incierto , se puede eliminar de la lista;
        2. "Aplicar" y compruebe que " ../src " apareció en todos los idiomas y configuraciones.
      2. Pestaña de símbolos:
        1. Botón Agregar: agregue el símbolo " __cplusplus " con el valor " 201103L " y el "Agregar a todas las configuraciones" y "Agregar a todos los idiomas" seleccionados - {F} más ;
        2. "Aplicar" y compruebe que en la configuración "gcc-debug", " __cplusplus " tiene el valor " 201103L ".
      3. Pestaña Ubicación de origen:
        1. Verifique que haya un elemento en la lista y apunte a “ /inet/src{G} , si hay algo más (por ejemplo, solo “ /inet ”), elimine lo que está y agregue (“Agregar carpeta ... ")" /inet/src ". Luego, el botón "Aplicar" y volver a {A} , porque Todos los filtros fueron eliminados durante la eliminación. Por cierto, " /inet " en realidad se puede dejar, todo va bien con él también, pero es mejor reducirlo al original " /inet/src ".
    2. Subsección "El preprocesador incluye rutas, Marcos, etc." > Pestaña "Proveedores":
      1. Seleccione "Configuración del compilador incorporado CDT GCC":
        1. En el grupo "Opciones de proveedor de configuración de idioma", haga clic en el enlace "Configuración del espacio de trabajo":
          1. Pestaña “Descubrimiento”: nuevamente seleccione “Configuración del compilador incorporado CDT GCC” y agregue “ -std=c++11 ” antes de “ ${FLAGS} ” en “Comando para obtener las especificaciones del compilador”, debería verse como ` ${COMMAND} -std=c++11 ${FLAGS} -E -P -v -dD "${INPUTS}" ` {F} , más detalles aquí y aquí ;
          2. botón "Aplicar", "Aceptar" (cerrar la ventana).
        2. mueva "Configuración del compilador incorporado CDT GCC" arriba de "Entradas del sistema de compilación administrado CDT" (para ambas configuraciones: "gcc-release" y "gcc-debug") {F} , más detalles - después de eso perderemos la capacidad de redefinir los caracteres "CDT Configuración del compilador incorporado de GCC "a través de" Entradas del sistema de compilación administradas por CDT "( " C / C ++ General "> " Rutas y símbolos "> " Símbolos "), solo puede anularlo agregando valores a las" Entradas de configuración de usuario CDT " “Entries” (: , .. “CDT Managed Build System Entries” “ __cplusplus ”; , “ __cplusplus __cplusplus ” “CDT Managed Build System Entries”, , );
        3. “Apply”, , “Entries” “GNU C++ ” “CDT GCC Build-in Compiler Settings” ( [ ] “Show build-in values” ) “ __cplusplus=201103L ” ( ).
    3. “Indexer”:
      1. “Build configuration for indexer” “gcc-release” {B} ;
      2. “Apply”.


{E} . Te lo explicaré. , 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 ):


  1. “/++ Build”:
    1. “Build Variables” (, “gcc-release [ Active ]”):
      1. “Add…”, “ CFLAGS ”, “String”, “ -O2 -fpredictive-commoning -march=native -freorder-blocks-and-partition -pipe ”;
      2. “Add…”, “ CXXFLAGS ”, “String”, “ -std=c++11 -O2 -fpredictive-commoning -march=native -freorder-blocks-and-partition -pipe ”;
      3. “Apply”.
    2. “Environment”:
      1. “Add…”, “ CFLAGS ”, “ ${CFLAGS} ”;
      2. “Add…”, “ CXXFLAGS ”, “ ${CXXFLAGS} ”;
      3. “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) . JSbookmark 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…):


Nuevo asistente de proyecto OMNeT ++


“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):


Ejecutar simulación desde la barra de herramientas


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, >:-), , , , ):


Git: flujo del sistema de control de historial


, , 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 icono de diferencia de etiqueta git , git tag.


Note : git diff , , ( , / ) ( AST ), Java .


# (Link Layer Topology Reveal)



# −1:


“package.ned” ( “Design” ), :


Editor de red


, broadcast :


  • – StandardHost;
  • – EtherSwitch.


“” ( ) Eth100M (: 100 Mbps; : 10 ). , 10 , , ? ( )


( “Source” ), (git tag a1_v0.2.0) diff . :


 package ‹<a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-ref:packages"> </a>›; //<a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-ref:directory-structure"> </a> import ‹<a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-lang:imports-and-name-resolution">  </a>›; network ‹<a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-lang:warmup:network">  </a>› {   @display(‹  , ,  ›);   <a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-ref:submodules">submodules</a>:       ‹<a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-lang:submodules"> </a>›: ‹ › { @display(‹  , , ›); }   <a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-ref:connections">connections</a>:       ‹ ›.‹<a href="https://omnetpp.org/doc/omnetpp/manual/#sec:ned-lang:gates"> </a>› <--> ‹  › <--> ‹ ›.‹ ›; } 


Warning : <a>...</a> – “” . , , , ( <strong>...</strong> , <em>...</em> ).



package ‹ ›; //

import ‹ ›;

network ‹
{
@display(‹ , , ›);
submodules :
›: ‹ › { @display(‹ , , ›); }
connections :
‹ ›.‹ › <--> ‹ › <--> ‹ ›.‹ ›;
}


“ ” (Gates) :


  1. Gates , , gate‹ ›.‹gate›[‹›] ”, – ‹ ›.‹gate› ++ ”.
  2. (: “ … <--> { delay = 100ms; } <--> … ”), / , ( broadcast : “ … <--> C <--> … ”), (: “ … <--> FastEthernet {per = 1e-6;} <--> … ”),
  3. Gates ( : output / input ; : --> / <-- ), ( : inout ; : <--> ). , , $i ” “ $o .



Warning : 13 20 ( 504 “Gateway Time-out”). 13 . ( ):


     <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:


Leer más →


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. (‑: “ ”)

DOI: 10.5281 / zenodo.1407029

#


. . – . – .

Source: https://habr.com/ru/post/es420327/


All Articles