Está en la página 1de 7

Universidad Nacional de Rosario

Facultad de Ciencias Exactas, Ingeniería y Agrimensura

Departamento de Sistemas e Informática

Informática Aplicada

Trabajo Práctico Nº 1

4 de Mayo de 2020
Autor/es:
Grupo Nº
Nombre y Apellido Nº de Legajo
BOVINA, Matias B-5751/7
LUJAN, Lionel L-2925/4

Corrigió Calificación
Trabajo practico N°1 Bovina, Matias – B-5751/7 Lujan, Lionel – L-2925/4

Enunciado A:
Descripción del Trabajo Práctico:

Un enrutador (router) es un dispositivo de comunicaciones digitales capaz de


transmitir tramas (frames) de datos, que son las unidades de transmisión en una
red como internet, por ejemplo. El enrutador recibe tramas de uno o más
dispositivos conectados y las transmite secuencialmente por un enlace de datos
de salida.

Para construir el software de operación de un enrutador WiFi se diseñará una


simulación mediante un programa en C donde las tramas de entrada tienen el
siguiente formato:

Todos los campos son binarios. El campo “Frame Control” indica la naturaleza y
prioridad de la trama, con el siguiente formato:

Donde ‘Bn’ es el bit n de los 16 del campo. Por ejemplo: B0...B1 indica un campo
de dos bits, B4...B7 uno de 4 bits (B4, B5, B6 y B7), B9 es un campo de un solo
bit y así con el resto.
El campo ‘Tipo’ (Type) indica la naturaleza de la trama según la tabla siguiente:

B2 y B3 Tipo

00 Trama de control

01 Trama de sincronización

10 Trama ordinaria

11 Trama de streaming

El programa de simulación que usted debe hacer leerá un conjunto de tramas de un


archivo llamado ‘TRAMAS.DAT’ que contiene la representación de un conjunto de
tramas de entrada.

1
Trabajo practico N°1 Bovina, Matias – B-5751/7 Lujan, Lionel – L-2925/4

Usted deberá crear este archivo pidiendo al usuario el número ‘n’ de tramas de entrada
que desea crear (250 < n < 2500). El archivo puede tener el formato que Ud. considere
más adecuado y debe contener tramas de todos los tipos generadas aleatoriamente.

El programa deberá generar un archivo de salida llamado ‘SALIDA_ROUTER.DAT’


clasificando las tramas según el campo ‘Type’:
Mediante un menú el programa deberá permitir al usuario de la simulación las
siguientes opciones de salida:

El archivo de salida debe contener grupos de 100 tramas, ordenadas según la opción
elegida.
Es decir, si el usuario elige la opción ‘C’, el archivo de salida debe mostrar primero un
75% de tramas de entrada de Control (en el orden en que aparecen en el archivo de
entrada), luego un 10% de tramas de entrada Ordinarias, un 10% de tramas de
Streaming y finalmente un 5% de tramas de Sincronización, repitiendo el ciclo hasta
procesar todas las tramas del archivo de entrada.

Al final de cada simulación el programa deberá mostrar en pantalla e incluir en el archivo


de salida una línea que indique:

Simulación ejecutada el dd/mm/aaaa hh:mm:ss en N seg. Tramas procesadas: K

2
Trabajo practico N°1 Bovina, Matias – B-5751/7 Lujan, Lionel – L-2925/4

Estrategia de resolución:
Para la implementación del programa fueron creadas 2 estructuras:

La primera, llamada Frame_format, es una estructura que representa cada uno de los
campos de una trama de datos. Los distintos campos dentro de la estructura son
representados con unsigned short int (2 Bytes). Los campos MAC_Destination,
MAC_Source, MAC_Router y MAC_AP son arreglos que contienen 3 enteros cortos cada
uno (para representar las distintas MAC), el campo CRC es un arreglo de 2 enteros cortos
y el campo Duration es representado por un solo entero corto. El campo Data está
representado por un arreglo de 1156 enteros cortos, ya que este es el tamaño máximo
que puede ocupar el campo data (1156*2 Bytes = 2312 Bytes)1.

El campo FrameControl estará representado por un campo de bits llamado FC_format,


donde se le asignan una cantidad de bits a cada uno de los campos que lo conforman.
Entre ellos se encuentra el campo Type (2 bits) que será el campo que tendremos que
analizar para determinar el tipo de trama.

Generador de tramas:

La primera parte del programa se encargará de la generación del archivo TRAMAS.DAT,


que contendrá un número n (entre 250 y 2500, indicando error si se ingresa un número
fuera de este rango) de tramas aleatorias. La función llamada frameGen() se encargará
de completar de manera aleatoria (utilizando el comando rand() de la librería <stdlib.h>)
los distintos campos de la estructura y del campo de bits2. Luego de generar una trama
la copiará en el archivo llamado TRAMAS.DAT.

Así, el usuario ingresara por teclado la cantidad n de tramas que desea generar, y
utilizando un while se ejecutará esta función n veces generando y copiando todas las
tramas. Luego se imprimirá por pantalla el mensaje “Archivo TRAMAS.DAT generado
exitosamente”.

Lectura del archivo y ordenamiento:

En la segunda parte del programa, se le solicitara al usuario que ingrese el tipo de


ordenamiento que se desea (letras C, T, O y S). Al ingresarla se abrirá el archivo
TRAMAS.DAT en modo lectura (indicando error si no se encuentra el archivo) y se creará
el archivo de salida llamado SALIDA_ROUTER.DAT, y se llamará a la función
ordenamiento(seleccion).

La función ordenamiento recibe como argumento el tipo de ordenamiento pedido según


la letra ingresada, y a través de esta se decide cuantas tramas de cada tipo se desea
ubicar en cada grupo. Además el programa realizará un conteo de cuantas tramas de
cada tipo hay en el archivo de entrada y almacenará esos valores en distintas variables
(que utilizará luego para saber si aún quedan tramas de ese tipo por ordenar). Luego de
esto la función entrara en un while que repetirá el siguiente ciclo mientras aun haya
tramas en el archivo que no hayan sido leídas y ordenadas:

3
Trabajo practico N°1 Bovina, Matias – B-5751/7 Lujan, Lionel – L-2925/4

1) El programa a través del puntero a archivo fichero_tramas lee una trama completa,
y se fija en el campo Type a ver si es una trama de tipo control. Si es, la copia en el
archivo de salida, si no la ignora y lee otra trama, así hasta leer y copiar la cantidad
de tramas de control pedidas (según el tipo de ordenamiento). Cada vez que copia
una trama de control aumenta el contador de tramas ordenadas y disminuye en 1
la cantidad de tramas de control que quedan por ordenar.
2) Al terminar de ordenar las de control repite el mismo ciclo para el resto de tipos
(sincronización, ordinaria y streaming), hasta conseguir (idealmente3) el grupo de
100 tramas ordenadas, guardando siempre la cantidad de tramas que quedan de
cada tipo y la ubicación de la última trama leída y ordenada de cada tipo (en las
variables control_cur, sincronizacion_cur, ordinaria_cur y streaming_cur)
3) Luego de ordenar un grupo de 100 tramas, comenzará a leer de nuevo y a ordenar
un nuevo grupo. Para no repetir las tramas ya ordenadas, se utiliza la función fseek
que reiniciara el puntero fichero_tramas y lo ubicará luego de la última trama leída
de cada tipo (antes de comenzar a buscar y ordenar estos).
4) El ciclo se repetirá hasta que ya no queden tramas por ordenar en el archivo de
salida.
Además, el programa almacenará la hora de comienzo del programa y la hora de
finalización, y por medio de esto calculara la diferencia4 e imprimirá “Archivo
SALIDA_ROUTER.DAT generado exitosamente” y también el tiempo de ejecución
del programa, además de la cantidad de tramas procesadas y la fecha. Por último,
pedirá que ingreses la letra “Y” y el programa finalizará.

Comentarios extras:
1) La idea inicial fue representar este campo por medio de un puntero. Utilizando
malloc y la función rand() alocábamos un valor aleatorio de memoria y
guardábamos la dirección en un puntero llamado *data. De esta manera cada
trama tenía una cantidad distinta de información (según la memoria dinámica
guardada aleatoriamente). El problema fue que al guardar una variable de tipo
puntero dentro de la estructura, cuando imprimíamos la estructura en el archivo
esa variable guardaba (lógicamente) la dirección de memoria de la información,
y no el contenido. No pudimos descubrir como guardar ese contenido. Además,
nos generaba un problema a la hora de leer el archivo para ordenarlo, ya que
cada trama tenía un tamaño distinto y la función fread (utilizada para leer
archivos binarios) solicita la cantidad de elementos del archivo y el tamaño de
estos (necesitan ser siempre del mismo tamaño).
Por este motivo, recurrimos a utilizar este arreglo, donde pedíamos memoria
para guardar la trama más grande posible y luego la llenábamos hasta un cierto
punto (aleatoriamente) y completábamos el resto con ceros.
2) La función rand genera un número aleatorio entre 0 Y RAND_MAX, donde este
valor es 32767. A pesar de que los campos de la estructura (del campo de bits)
tienen delimitado un entero máximo (dado por la cantidad de bits reservado
para cada campo), si se ingresa un número mayor a este el campo guardará
automáticamente los bits menos significativos de su representación.
Por ej.: la representación binaria del entero 6 es 110 (utiliza 3 bits). Si
almacenáramos un 6 en un campo que tiene reservado solo 2 bits, guardaría 10
(que sería realmente el entero 2).

4
Trabajo practico N°1 Bovina, Matias – B-5751/7 Lujan, Lionel – L-2925/4

A pesar de esto, aunque no guarde el número deseado, se sigue manteniendo


la aleatoriedad por lo que no afecta al funcionamiento.
3) Idealmente el archivo de salida debe ordenar grupos de 100 tramas con un
porcentaje de tramas de cada tipo. Al idear la solución, se presentó el problema
de que ocurría si en el archivo TRAMAS.DAT (generado aleatoriamente) no había
suficientes tramas de algún tipo para cubrir el porcentaje deseado. La solución
propuesta fue que, mientras haya tramas suficientes se hagan grupos de 100
tramas, pero cuando no haya suficientes tramas de cierto tipo, se coloquen las
que haya y se mantengan la misma cantidad inicial del resto de tipos de tramas.
De esta forma es posible que los últimos grupos de tramas ya no sean de 100.
4) Para calcular el tiempo de ejecución inicialmente guardábamos la hora de
comienzo y de final utilizando las funciones de la librería <time.h>. El problema
fue que la diferencia entre dos instantes la calcula utilizando números en
segundos (enteros), y como el tiempo de ejecución es (normalmente o al menos
en nuestra PC) menor a 1 seg, por lo que el “tiempo de ejecución” resultaba 0.
Para solucionarlo utilizamos otras funciones de la librería <Windows.h>, que
tienen una mejor resolución (en milisegundos).

Pruebas y respuestas obtenidas:

5
Trabajo practico N°1 Bovina, Matias – B-5751/7 Lujan, Lionel – L-2925/4

Ejemplo de un archivo de salida SALIDA_ROUTER.DAT

También podría gustarte