Dos protocolos de transporte utilizados para transferir archivos incluyen: TCP y UDP. UDP es un protocolo poco confiable, mientras que TCP proporciona confiabilidad, control de flujo y control de congestión, pero tiene una fase de establecimiento de conexión explícita, que algunas aplicaciones pueden no considerar deseable. El objetivo de este proyecto es diseñar e implementar una aplicación de transferencia de archivos que tenga todas las buenas características de TCP sin la fase de establecimiento de conexión.
El servidor y cliente UDP utiliza el siguiente formato de encabezado:
El servidor recibe una solicitud de archivo del cliente. Extrae el nombre del archivo de la solicitud y obtiene el contenido del archivo en un búfer. Luego segmenta el archivo en fragmentos de 1450 bytes de tamaño según lo admitido por el encabezado.
Hay dos tamaños de ventana a considerar:
El servidor comienza a enviar segmentos de archivos hasta el mínimo del tamaño de la ventana de congestión y el tamaño de la ventana anunciada. Después de enviar todos los segmentos en una ventana, espera recibir un acuse de recibo. Cuando se recibe un acuse de recibo para un número de secuencia que es menor que el siguiente número de secuencia que se enviará, significa que algún segmento anterior no se recibió correctamente y el servidor acepta los 3 acuses de recibo duplicados del cliente. Luego establece el siguiente número de secuencia según el acuse de recibo recibido. Luego de recibir el acuse de recibo acumulado, continúa enviando los segmentos en la siguiente ventana. Cuando se reciben acuses de recibo duplicados, el servidor comenzará a enviar segmentos del paquete que no se recibió correctamente.
Implementé el algoritmo de Jacobson/Karel para estimar el tiempo de ida y vuelta (RTT) de los paquetes que recibirá el cliente y el acuse de recibo recibido por el servidor. Si el servidor no recibe confirmación dentro de RTT, retransmitirá esos paquetes nuevamente.
Pseudocódigo:
Estimated_RTT = (1-α) Estimated RTT + (α) Sample_RTT
In the original TCP Specification, α=.0125
Jacobson/Karels included a variation component to the calculation for the Estimated_RTT
Estimated_RTT = Estimated_RTT + δ (Sample_RTT-Estimated_RTT)
Deviation = Deviation + δ (|Sample_RTT- Estimated_RTT|- Deviation)
Timeout = μ * Estimated_RTT + φ * Deviation
Typically φ=4, μ = 1, δ is between 0 and 1
El servidor comienza enviando 1 segmento. Luego, siguen 2 fases de control de la congestión:
Inicio lento: el tamaño del segmento aumenta exponencialmente hasta que el receptor lo reconoce correctamente dentro del tiempo de espera y el tamaño de la ventana de congestión es menor que ssthresh, que está establecido en 64000 bytes.
Prevención de congestión: cuando el tamaño de la ventana de congestión se vuelve mayor o igual que ssthresh, el tamaño de la ventana de congestión aumenta linealmente en 1 segmento.
Tiempo de espera: se calcula utilizando el algoritmo de Jacobson/Karel indicado anteriormente. Cuando se agota el tiempo de espera, ssthresh se establece en la mitad del valor de la ventana de congestión y la ventana de congestión se restablece al tamaño de 1 segmento.
vagrant up
Esto iniciará tanto el servidor como el cliente.
vagrant ssh reliableUDPServer
vagrant ssh reliableUDPClient
make
./Server port advertised_window
El servidor acepta los siguientes argumentos de línea de comandos:
puerto: número de puerto que se utilizará para la comunicación
ventana_publicitada: el número de bytes que el servidor puede enviar antes de esperar una confirmación
./Client server_host_name port file_name advertised_window
El cliente acepta los siguientes argumentos de línea de comandos:
puerto y ventana_anunciada: igual que la del servidor
server_host_name: nombre de host del servidor
file_name: el nombre del archivo solicitado por el cliente
Una vez que el código se ejecute correctamente, encontrará el archivo que solicitó el cliente en la carpeta ReliableUDPClient.
Enfoque de arriba hacia abajo de redes de computadoras