Для передачи файлов используются два транспортных протокола: TCP и UDP. UDP — ненадежный протокол, тогда как TCP обеспечивает надежность, управление потоком данных и контроль перегрузки, но имеет явную фазу установления соединения, что некоторым приложениям может быть нежелательно. Целью этого проекта является разработка и реализация приложения для передачи файлов, которое обладает всеми преимуществами TCP без этапа установления соединения.
UDP-сервер и клиент используют следующий формат заголовка:
Сервер получает запрос файла от клиента. Он извлекает имя файла из запроса и получает содержимое файла в буфер. Затем он сегментирует файл на фрагменты размером 1450 байт в соответствии с заголовком.
Следует учитывать два размера окон:
Сервер начинает отправлять сегменты файлов до достижения минимального размера окна перегрузки и объявленного размера окна. После отправки всех сегментов в окне оно ожидает получения подтверждения. Когда подтверждение получено для порядкового номера, который меньше следующего порядкового номера, который должен быть отправлен, это означает, что какой-то предыдущий сегмент был получен неправильно, и сервер принимает 3 повторяющихся подтверждения от клиента. Затем он устанавливает следующий порядковый номер на основе полученного подтверждения. После получения совокупного подтверждения он продолжает отправку сегментов в следующем окне. При получении дубликатов подтверждений сервер начнет отправлять сегменты из неправильно полученного пакета.
Реализован алгоритм Джейкобсона/Карела для оценки времени прохождения туда и обратно (RTT) для пакетов, которые должны быть получены клиентом, и подтверждения, полученного сервером. Если сервер не получит подтверждения в рамках RTT, он повторно передаст эти пакеты.
Псевдокод:
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
Сервер запускается с отправки 1 сегмента. Затем следуют 2 этапа контроля перегрузок:
Медленный старт: размер сегмента увеличивается в геометрической прогрессии до тех пор, пока он не будет правильно подтвержден получателем в течение тайм-аута, а размер окна перегрузки не станет меньше, чем ssthresh, который установлен на 64000 байт.
Предотвращение перегрузки: когда размер окна перегрузки становится больше или равен ssthresh, размер окна перегрузки увеличивается линейно на 1 размер сегмента.
Тайм-аут: рассчитывается с использованием алгоритма Джейкобсона/Карела, приведенного выше. Когда происходит таймаут, ssthresh устанавливается на половину значения окна перегрузки, а окно перегрузки сбрасывается до размера 1 сегмента.
vagrant up
Это загрузит как сервер, так и клиентские машины.
vagrant ssh reliableUDPServer
vagrant ssh reliableUDPClient
make
./Server port advertised_window
Сервер принимает следующие аргументы командной строки:
порт: номер порта, который будет использоваться для связи
рекламируемое_окно: количество байтов, которое серверу разрешено отправить до ожидания подтверждения.
./Client server_host_name port file_name advertised_window
Клиент принимает следующие аргументы командной строки:
порт и рекламируемое_окно: такие же, как у сервера
server_host_name: имя хоста сервера
имя_файла: имя файла, запрошенного клиентом
После успешного запуска кода вы найдете файл, запрошенный клиентом, в папке ReliableUDPClient.
Компьютерные сети: подход «сверху вниз»