IIC2333 / foro-2019-1

Foro oficial del curso IIC2333 - Sistemas Operativos y Redes, semestre 2019-1.
2 stars 0 forks source link

Construcción del paquete #124

Closed jpjoublan closed 5 years ago

jpjoublan commented 5 years ago

Hola! Tenemos una duda con la construcción del paquete/protocolo. No entendemos bien el tipo que deben tener los elementos del paquete, ¿los dos primeros bytes (MessageType y PayloadSize) tienen que ser unsigned int o unsigned char? Y después, cuando agregamos el contenido, este es unsigned char?

En caso de no usarse esos tipos, se pueden mandar mensajes como char por ejemplo? Y, por último, hay alguna función que nos recomienden para armar el paquete a enviar, alguna para escribir bytes en un buffer?

fprebolledo commented 5 years ago

misma pregunta! lo que he hehcho hasta ahora es castear todo el buffer como unsigned char, está bien así ?

nivek0o0 commented 5 years ago

Hola, no se compliquen y utilicen arreglos o buffers de char nomás. Luego, un elemento de este buffer puede ser casteado o asignado a una variable int si necesitan interpretarlo como número. Les aconsejo mirar el nuevo código de ejemplo que subimos. Saludos!

malopez16 commented 5 years ago

Hola! @nivek0o0 Con respecto a ese código nuevo de ejemplo, se hace algo como

      package[0] = 19;
      package[1] = msgLen;

Siendo package un arreglo de chars, cada espacio en ese arreglo es de 1 byte. Los números son de 2 ó 4 bytes. No logro entender cómo estamos metiendo un int de ese tamaño, en un espacio de char de 1 byte. ¿Está correcto? Por otro lado, si quisiéramos mandar chars, para type ids de 2 dígitos, necesitaríamos mandar al menos 2 chars, uno para cada dígito, por lo que en teoría el número no entraría en lo que exige el protocolo (1 byte). ¿O no?

Edit: De hecho, en mi sistema:

printf("%ld", sizeof("19")); me arroja 3 bytes, 1 de cada char + el de término) printf("%ld", sizeof(19)); me arroja 4 bytes, 2 por cada dígito de int.

Ninguno de los dos cabe en 1 byte... :(

nivek0o0 commented 5 years ago

Hola @malopez16,

el tamaño por defecto de los números enteros en C es de 4 bytes. Eso se diseñó así para poder representar números entre -2,147,483,648 y 2,147,483,647 (el primer bit para el signo, los siguientes 31 para el valor). Esto no significa que no se puedan guardar enteros en 1, 2 o 3 bytes, es perfectamente posible, solo que el rango de valores será más reducido. En tu ejemplo, estás interpretando mal el tamaño de 19, no son 2 bytes por cada dígito, son 4 bytes para todo el número, por la razón que dije antes. De hecho, si miras el tamaño de un numero de más cifras también será 4.

Los char, en cambio, se diseñaron para almacenarse en 1 byte en la memoria. Esto implica que en un char yo puedo almacenar números enteros entre -128 y 127. La gracia es que los char también pueden representar caracteres, letras, dígitos, símbolos de puntuación, entre otros, cuando son impresos como %c. La forma en que printf() hace esta traducción es mediante los códigos ASCII. Imaginemos un char cuyo binario es 01000001, este se traduce al decimal 65, y eso corresponde a la letra A mayúscula. (según esta tabla). De esta forma, hacer char x = 'A'; es equivalente a char x = 65;, ya que ambas instrucciones van a almacenar el binario 01000001 a la memoria. Incluso, con ambas definiciones yo podría hacer x == 'A' o x == 65 y darían true. La diferencia está en cómo interpretamos ese binario. Los strings se almacenan como arreglos de char, donde cada letra se guarda en un char. En tu ejemplo, el char que está almacenando '1' tendría el valor decimal 49, mientras que el '9' se almacena como 57 y el nulo final como 0.

Explicado eso, lo que hace el código de ejemplo y queremos que ustedes hagan en el proyecto es aprovechar al máximo cada byte transmitido. Dado que no tenemos más de 127 tipos de paquetes, con un byte es más que suficiente para comunciar el ID. Por eso se define el entero 19 (no el string "19") en el primer byte del arreglo package. Dicha asignación almacenará el binario 00010011 en esa posición.

La consecuencia de esta práctica es que el PayloadSize tiene una cota superior para su valor (porque contamos con solo 1 byte), lo que afectará en la forma en que transmiten un payload, como la imagen.

Cualquier duda quedo atento! Saludos