Dois protocolos de transporte usados para transferir arquivos incluem: TCP e UDP. O UDP é um protocolo não confiável, enquanto o TCP fornece confiabilidade, controle de fluxo e controle de congestionamento, mas possui uma fase explícita de estabelecimento de conexão, que algumas aplicações podem não achar desejável. O objetivo deste projeto é projetar e implementar uma aplicação de transferência de arquivos que possua todos os bons recursos do TCP sem a fase de estabelecimento de conexão.
O servidor e cliente UDP usa o seguinte formato de cabeçalho:
O servidor recebe solicitação de arquivo do cliente. Ele extrai o nome do arquivo da solicitação e obtém o conteúdo do arquivo em um buffer. Em seguida, ele segmenta o arquivo em pedaços de tamanho 1450 bytes, conforme suportado pelo cabeçalho.
Existem dois tamanhos de janela a serem considerados:
O servidor começa a enviar segmentos de arquivo até o tamanho mínimo da janela de congestionamento e o tamanho da janela anunciado. Após enviar todos os segmentos em uma janela, espera receber um reconhecimento. Quando uma confirmação é recebida para um número de sequência menor que o próximo número de sequência a ser enviado, significa que algum segmento anterior não foi recebido corretamente e o servidor aceita as 3 confirmações duplicadas do cliente. Em seguida, ele define o próximo número de sequência com base na confirmação recebida. Após receber o reconhecimento cumulativo, continua enviando os segmentos na próxima janela. Quando forem recebidas confirmações duplicadas, o servidor começará a enviar segmentos do pacote que não foi recebido corretamente.
Implementado algoritmo de Jacobson/Karel para estimativa do tempo de ida e volta (RTT) dos pacotes a serem recebidos pelo cliente e confirmação recebida pelo servidor. Se o servidor não obtiver confirmação no RTT, ele retransmitirá esses pacotes novamente.
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
O servidor começa enviando 1 segmento. Seguem-se então 2 fases de controle de congestionamento:
Início lento: o tamanho do segmento aumenta exponencialmente até que seja reconhecido corretamente pelo receptor dentro do tempo limite e o tamanho da janela de congestionamento seja menor que o ssthresh que é definido como 64.000 bytes.
Prevenção de congestionamento: quando o tamanho da janela de congestionamento se torna maior ou igual a ssthresh, o tamanho da janela de congestionamento aumenta linearmente em 1 tamanho de segmento.
Tempo limite: É calculado usando o algoritmo de Jacobson/Karel fornecido acima. Quando ocorre um tempo limite, o ssthresh é definido como metade do valor da janela de congestionamento e a janela de congestionamento é redefinida para o tamanho de 1 segmento.
vagrant up
Isso inicializará as máquinas servidor e cliente
vagrant ssh reliableUDPServer
vagrant ssh reliableUDPClient
make
./Server port advertised_window
O servidor aceita os seguintes argumentos de linha de comando:
porta: número da porta a ser usada para comunicação
anunciado_window: o número de bytes que o servidor pode enviar antes de aguardar uma confirmação
./Client server_host_name port file_name advertised_window
O cliente aceita os seguintes argumentos de linha de comando:
porta e janela_anunciada: iguais às do servidor
server_host_name: nome do host do servidor
file_name: o nome do arquivo solicitado pelo cliente
Assim que o código for executado com sucesso, você encontrará o arquivo solicitado pelo cliente na pasta ReliableUDPClient.
Abordagem de redes de computadores de cima para baixo