IIC2233 / Syllabus

147 stars 13 forks source link

Pregunta, Experiencia 3 #616

Open gracie-14 opened 2 days ago

gracie-14 commented 2 days ago

Prerrequisitos

(Marcar colocando una X entre los corchetes los ítems que ya hiciste, así: "[X]")

Duda

Hola! Estoy repasando la solución de la Experiencia 3, y tengo una pregunta sobre la función listen_client_thread() del Servidor.

¿Por qué el cliente está desconectado si recibe un largo de 0? ¿Por qué no verifica el largo/contenido de la parte dos del mensaje? ¿No es posible que el cliente se desconecte mientras envía la segunda parte del mensaje?

Screenshot 2024-11-13 at 9 34 40 PM

Además, vi que utiliza except Exception, que nosotros no podemos utilizar. ¿Cuáles tipos de errores pueden ocurrir en este paso? (para saber que poner después de except si hay un error).

Finalmente, en la función anterior recibir_bytes(), hay una parte del código que retorna menos bytes de lo esperado si solo llegan algunos, y dice que va a intentar ver el mensaje. No entiendo como está manejando una situación con un envío incompleto. Me imagino que en la función manejar_mensaje() habría un KeyError y por eso se rompería la conexión? Que pasa si es incompleto, pero no porque el cliente se desconectó, sino por otra problema con el mensaje?

Screenshot 2024-11-13 at 9 45 24 PM

Gracias por la ayuda!

GonzaloMatus commented 1 day ago

Hola,

El servidor puede deducir que el cliente se ha desconectado repentinamente debido a cómo funcionan los sockets en el sistema operativo. Cuando un cliente se desconecta inesperadamente, el sistema operativo, siguiendo el protocolo TCP, notifica al servidor con un mensaje vacío.

Respecto a tu segunda pregunta, sí, es posible que el cliente se caiga mientras envía la segunda parte del mensaje, o incluso que se produzca otro tipo de error durante el envío. Si esto ocurre, el error probablemente será detectado en el bloque try-except. En este caso, si pickle no puede deserializar el mensaje porque la segunda parte de los datos está incompleta o corrupta, lanzará un pickle.UnpicklingError. Este es el error que se maneja en la línea:

mensaje = pickle.loads(bytes_mensaje_parte_2)

Si se produce cualquier otro tipo de error inesperado, el bloque except capturará la excepción. Para identificar el tipo de error, puedes usar el siguiente código como base:

try:
    1 / 0  # Esto generará una ZeroDivisionError
except Exception as e:
    print(f"Se ha producido una excepción: {type(e).__name__}")
    print(f"Argumentos de la excepción: {e.args}")
    print(f"Mensaje de la excepción: {e}")

Finalmente, en cuanto a tu pregunta sobre la función manejar_mensaje() si el cliente se desconecta o el mensaje está incompleto, el error será detectado en el momento en que intentas cargar la segunda parte del mensaje con pickle.loads(). Si el servidor recibe datos incompletos o corruptos, este será el lugar donde se lanzará la excepción, y no llegará a ejecutarse la función manejar_mensaje() con datos incompletos.

gracie-14 commented 1 day ago

Muchas gracias! Entiendo mejor ahora.

Solo quiero aclarar, ¿podemos usar except Exception as e: en la Tarea? Yo pensé que eso fuera mala práctica.

Gracias!

gracie-14 commented 1 day ago

Perdón, tengo otra duda después de releer esto. ¿La razón que solo hace if largo_mensaje == 0 y no para los otros datos que recibe es porque es el primero? ¿Así que si el cliente se desconecta, éste sería el variable que recibe el mensaje vacío?

GonzaloMatus commented 23 hours ago

Hola sobre tu segunda respuesta, estas correcto sobre lo que planteas.

Respecto a tu primera respuesta sobre si se puede utilizar except Exception as e en la tarea te la puedo contestar en una nueva issue.

¡Suerte con la tarea!

gracie-14 commented 23 hours ago

Ok gracias!!