PRÁCTICA 1: Simulación de Protocolo de Control de Flujo Simple Introducción La práctica consistirá en el diseño e implementación de un Protocolo de Control de Flujo Simple desarrollado con la herramienta OPNET. El escenario planteado se compone de un emisor y un receptor. El emisor enviará paquetes cada cierto tiempo al receptor, y éste tendrá en cuenta el intervalo de tiempo transcurrido desde el último paquete recibido para enviar una trama ACK como reclamo de la siguiente trama esperada. Dado que no es de interés en esta práctica la comunicación duplex, el receptor destruirá el paquete una vez recibido y escribirá en fichero el número de trama recibida y el instante en el que ocurrió dicho evento. Para ello, realizaremos el diseño manejando los tres niveles de abstracción que ofrece dicha herramienta: 1. Modelo de Procesos 2. Modelo de Nodos 3. Modelo de Proyecto Por simplicidad, comenzaremos el diseño a nivel de nodos, a los cuales se les asignarán su correspondiente modelo de nivel de procesos. Modelo de Nodos Diseñaremos el escenario planteado como dos nodos conectados de forma unidireccional desde el emisor hacia el receptor. Para ello, seguiremos estos pasos: 1. Crear un nuevo modelo de nodos. 2. Crear dos procesadores y llamarlos emisor y receptor. 3. Crear un stream de paquetes que una al emisor con el receptor. 4. Guardar el modelo con el nombre proto_parada_espera_nodos (la propia herramienta salvará con la extensión correcta). A continuación, pasaremos a integrar a cada nodo un modelo de procesos que defina su comportamiento. 5. Pulsamos el botón derecho sobre el emisor y, en sus atributos, le asignamos como Modelo de Procesos aquel que genera y envía paquetes: simple_source. Pág 1 de 5
Puesto que modificaremos este modelo de procesos, lo guardaremos en nuestra carpeta (Save as ) con el nombre proto_parada_espera_procesos_emisor, para no sobrescribir el modelo original. Al nodo receptor le asignaremos el modelo de procesos que crearemos a continuación, cuya misión será la de contar los paquetes que reciba e imprimir los mensajes correspondientes en un fichero. Modelo de Procesos Crearemos el modelo de procesos del nodo receptor de forma que sea capaz de contar los paquetes recibidos así como monitorizar los intervalos de tiempo en los que recibe dichos paquetes. Para ello, llevaremos a cabo las siguientes acciones: 1. Crear un nuevo modelo de procesos con 3 estados como se ven en la figura: 2. Crearemos las variables que manejará este nodo. Tendremos en cuenta las variables pertinentes que nos permitan llevar la cuenta del número de paquetes recibidos y del tiempo que ha transcurrido desde el último paquete recibido. Para ello, creamos la variable pk_count y la variable sello_tiempo (indica el instante en el que se recibió el paquete anterior). 3. Para poder realizar posteriores análisis estadísticos, necesitamos una variable del tipo Stathandle que recoja toda la información para su estudio. 4. También registraremos las tramas ack s que deberían enviarse al emisor. Por ello, requerimos de un variable ack para llevar su cuenta. 5. Para poder imprimir en fichero todos estos mensajes, necesitamos una última variable que nos permita manejar dicho fichero. Esta será llamada fichero. (Los nombres pueden ser diferentes, siempre que luego se hagan referencia a los que realmente pongamos). Para introducir estas variables, debemos pulsar sobre State Variables. Pág 2 de 5
Este modelo representa el comportamiento que debe seguir el nodo receptor de paquetes. Comienza en el estado inicial, donde se inicializarán todas las variables que vayamos a utilizar. Para ello, deberemos: 1. Iniciar el contador de paquetes a 0. 2. Inicial la marca de tiempo del último paquete recibido a 0. 3. Crear el fichero de salida del receptor para imprimir todos los mensajes. El código que debe tener este estado en su Enter Executive (también podría ponerse en el Exit Executive, pues se ejecutará todo el código una vez salga de este estado) debe ser el siguiente: pk_count = 0; sello_tiempo = 0.0; fichero = fopen ("C:\\ <ruta por defecto> \\salida_recepcion.txt", "w"); fprintf (fichero, "FICHERO DE SALIDA DEL RECEPTOR\n"); pk_cnt_stathandle = op_stat_reg ("packet count", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); Una vez hecho esto, transita incondicionalmente al estado de espera, donde se mantendrá a la espera de la interrupción ARRIVAL que deberemos definir más adelante. Por mejorar el comportamiento, y por cuestiones de coherencia, estableceremos también la transición default predefinida por la herramienta OPNET, que realizará una transición al mismo estado en caso de que se produzca cualquier otro tipo de interrupción. Para transitar al estado de llegada, es necesario que la interrupción que se produzca en el Simulador sea de tipo OPC_INTRPT_STRM (predefinida por la herramienta OPNET). De este modo, podemos definir en el Header Block el siguiente párrafo: #include <stdio.h> #define ARRIVAL (op_intrpt_type () == OPC_INTRPT_STRM) En el estado de llegada, debemos realizar las siguientes operaciones: 1. Incrementar el número de paquetes recibidos. 2. Calcular el intervalo de tiempo transcurrido desde el último paquete recibido. 3. Actuar en consecuencia: Enviar trama ACK si el tiempo transcurrido desde que se recibió la última trama supera los 9 segundos. Pág 3 de 5
4. Actualizar la variable que marca el instante en el que se ha recibido el último paquete. 5. Destruir el paquete recibido. 6. Registrar en la variable estadística la información relevante al número de paquetes recibidos. El código que debe tener el Enter Executive de este estado es el siguiente: ++pk_count; fprintf (fichero, "---------------------------------------------------\n\r"); fprintf (fichero, "tiempo_actual: %d \n\r", (int)op_sim_time() ); fprintf (fichero, "sello tiempo: %d \n\r", (int)sello_tiempo); // Llegamos al último evento de la simulación if ( op_sim_at_end () ){ fprintf (fichero, "*****FIN SIMULACION*****\n\r"); fclose (fichero); } /* Calculamos si la diferencia de tiempo entre llegadas de paquetes es mayor de 9 segs. Si lo es, enviamos trama ACK desenchando todos los paquetes */ if ( (op_sim_time() - sello_tiempo) > 9.0 ){ //escribir_fichero ( op_sim_time() - sello_tiempo ); fprintf (fichero, "%d : envio ACK por tiempo excedido: %d \n\r", (int)op_sim_time(), (int)(op_sim_time() - sello_tiempo)); } //Actualizamos el sello de tiempo para posteriores comparaciones sello_tiempo = op_sim_time(); fprintf (fichero, "---------------------------------------------------\n\r"); op_pk_destroy (op_pk_get (op_intrpt_strm ())); op_stat_write (pk_cnt_stathandle, pk_count); Para poder realizar posteriores análisis estadísticos, debemos registrar la variable estadísitica en Interfaces > Local Statistics. Guardamos el modelo de nodos como proto_parada_espera_procesos_receptor. Modelo de Nodos (continuación) Volvemos al modelo de nodos anterior, y, al receptor le asignamos como modelo de procesos el recien creado proto_parada_espera_procesos_receptor. Dado que en esta práctica es de relevante interés el envío en diferentes instantes de tiempo de paquetes, el emisor deberá tomar diferentes distribuciones de envio de paquetes, para su posterior estudio. Dado que el hacerlo desde el nivel de nodos es algo tedioso, Pág 4 de 5
promocionamos este atributo del nodo emisor hacia el modelo de proyecto, para cambiarlo desde este nivel superior de abstracción. Para ello, pulsamos el botón derecho sobre el nodo emisor, y en sus atributos,pulsamos el botón derecho sobre el atributo Packet Interarrival Time y seleccionamos Promoted. Para seleccionar las variables estadísticas que estudiaremos, seleccionamos Interfaces > Node Statistics y añadimos la del receptor de paquetes que cuenta los paquetes que recibe. Puesto que solo nos interesa el modelo de forma fija, deseleccionamos la opción de modelo movil y satelite desde Interfaces > Node Interfaces, en el apartado Node Types. Guardamos el modelo de nodos. Modelo de Proyecto Creamos un nuevo modelo de proyecto, con las siguientes carácterísticas: Nombre Proyecto: proto_parada_espera_proyecto Escenario: escenario_1 Escala: Office, 100 x 100 metros Creamos una nueva paleta en la que solo introduciremos el modelo de nodos creado. Para ello, limpiamos la paleta (clear) y pulsamos sobre Node Models. Ahí, incluimos el modelo de nodos que creamos: proto_parada_espera_nodos. Guardamos la paleta. Ahora, colocamos un nodo en el escenario. En sus atributos, seleccionamos las distribuciónes del nodo emisor que deseamos para su estudio y comparación. Podemos empezar con una distribución constante, en la que se envien paquetes cada segundo. Otra distribución es la Uniforme (2, 15), de forma que enviará paquetes de forma aleatoria desde cada 2 hasta cada 15 segundos. El alumno podrá probar otras distribuciones para comprobar el correcto comportamiento del protocolo creado. Pág 5 de 5