sisoputnfrba / foro

Foro de consultas para el trabajo práctico
151 stars 7 forks source link

Funcion recibir_paquete del tp0 #3601

Closed rood8592 closed 5 months ago

rood8592 commented 6 months ago

Buenas, la función recibir_paquete del tp0 esta hecha de forma genérica? Porque la usamos para mandar un struct pcb como se muestra en la imagen y todos los datos se recibieron correctamente. Pero después observamos que la función parecería estar hecha para recibir cadena de caracteres únicamente que es lo que hacia en el tp0, osea no sabemos por qué razon funcionó si es que la funcion solo esta preparada para recibir char. Luego de crear el paquete, llamamos cinco veces a la funcion agregar_a_paquete tambien del tp0, para los cinco tipos de dato distintos que tiene nuestro t_pcb, lo enviamos con enviar_paquete y lo recibimos en una lista con la funcion recibir_paquete.

typedef struct
{
    uint8_t AX;
    uint8_t BX;
    uint8_t CX;
    uint8_t DX;
    uint32_t EAX;
    uint32_t EBX;
    uint32_t ECX;
    uint32_t EDX;
}t_registros_generales;

typedef struct
{
   int pid;
   uint32_t pc;
   int quantum;
   char* estado;
   t_registros_generales registros_CPU;
} t_pcb;
iago64 commented 6 months ago

Buenas! Cómo va?

Lo copado del par de funciones enviar_paquete() y recibir_paquete() es que tienen el código y pueden analizarlo por su cuenta, pero un poco si, esas funciones se pensaron para mandar cosas relativamente "simples" como un char, pero como explicamos en la Guía de Serialización todo en C es una posición de memoria y por lo tanto, se puede resumir como un `void ` y es por eso que podes enviar y recibir tus structs sin mayores inconvenientes.

El problema lo van a empezar a tener en el momento en el que empiecen a mandar información que no es fija por ejemplo una lista, ahi si van a tener que ponerse creativos con el uso de las funciones del TP0 si las quieren reutilizar.

Saludos.-

rood8592 commented 6 months ago

Ok, gracias. Y otra duda, en este momento, como dije antes hicimos 5 agregar a paquete, una por cada dato del pcb (pid, pc, quantum, estado, registros_cpu). Cuando intente agrupar todo en un solo llamado a agregar_paquete, pasandole el paquete, el pcb entero (no dato por dato) y el tamaño total que lo sume con sizeof() ahí ya me tiraba segmentation fault, por qué podría suceder esto? Que agregando todo por separado al paquete funciona y meterlo todo de una el pcb no funciona.

iago64 commented 6 months ago

Buenas! Cómo va?

El problema del segment fault en si, te dice que te mandaste una con la memoria, sin ver código es dificil pero me juego a pensar que le estas haciendo el sizeof() de un puntero y eso es lo que te hace volar todo por los aires. Pero como para sumar una herramienta mas de análisis, te recomiendo que corras con Valgrind y veas que te dice, si no lo llegas a entender, copiate el output de Valgrind aca y lo vemos en conjunto.

Saludos.-

FredeHG commented 6 months ago

Hola @rood8592 Quedo resuelta la duda? Cerramos el issue?

rood8592 commented 6 months ago

Sisi, ahí lo cierro. Gracias!

rood8592 commented 5 months ago

Buenas, reabro este issue porque nos surgió una duda con respecto a las funciones del tp0, en el siguiente código estamos simulando mandar 3 ints dentro de un struct (representarian dir fisica, base y tamanio) y todo funciona correctamente, osea se recibe bien y valgrind no nos dice nada ¿Estaría bien pasarle por parámetro el struct entero a agregar a paquete, podría fallar en algún contexto con alguna maquina, o debería agregar al paquete dato por dato (int por int)? Se que ese "sizeof" nos devuelve 12 porque cada int del struct ocupa 4 bytes. Más que nada porque por ahí en nuestras maquinas funciona bien pero no sabemos en otras como iría la cosa.

ENVIO

t_prueba new;
new.a = 2;
new.b = 4;
new.c = 6;

t_paquete* paquete = crear_paquete(25); //codigo op random
agregar_a_paquete(paquete,&new,sizeof(t_prueba));
new.a = 8;
new.b =10;
new.c = 12;
agregar_a_paquete(paquete,&new,sizeof(t_prueba));
enviar_paquete(paquete,fd_cpu);
eliminar_paquete(paquete);

RECEPCIÓN

recibir_operacion(fd_conexion_memoria);
t_list* paquete = recibir_paquete(fd_conexion_memoria);
t_prueba* new = list_get(paquete,0);
t_prueba* new2 = list_get(paquete,1);

printf("\nVALOR A1: %d\n",new->a);
printf("\nVALOR B1: %d\n",new->b);
printf("\nVALOR B1: %d\n",new->c);
printf("\nVALOR A2: %d\n",new2->a);
printf("\nVALOR B2: %d\n",new2->b);
printf("\nVALOR B2: %d\n",new2->c);
mefederico commented 5 months ago

Hola buenas!

los problemas que puedan tener entre computadoras se da más entre tipos de datos, en este caso si en el struct usan uint32_t o algo similar no van a tener ningún problema dado que un struct no es mas que poner un dato al lado del otro

Donde se tendrían problemas es si en el struct ponen un puntero, porque lo estarían pasando en la dirección donde esta el dato de una computadora a otra, y eso en la otra computadora no tiene mucho sentido

Les dejo la guía de serialización por si necesitan pegarle una mirada, específicamente lo ultimo que menciono esta en estructuras dinamicas

Saludos!

rood8592 commented 5 months ago

Buenas, muchas gracias! ¿Un tipo de dato int podría ser? ¿O es recomendable los tipos uint32_t, uint8_t, etc?

mefederico commented 5 months ago

No vas a tener problema en general, pero en la documentacion de sistemas operativos dejamos una explicación de porque es buena idea usar int32_t o uint32_t y no int solo

Saludos!

rood8592 commented 5 months ago

Ok, muchas gracias!