Хорошим компромиссом между немедленным и отложенным подтверждением можно считать следующую схему. При получении сегмента адресат не отправляет подтверждение, если, во-первых, сегмент не содержит флага PSH
(дающего основание полагать, что вслед за полученным сегментом вскоре последуют дополнительные данные), и, во-вторых, отсутствует необходимость отправки обновленного значения окна.
Тем не менее получатель должен установить таймер, который позволит послать подтверждение, если в передаче данных произошел определенный перерыв, что может быть вызвано, например, потерей сегментов.
Старые реализации TCP начинали передачу, отправляя сегменты в пределах предлагаемого окна, не дожидаясь подтверждения. Это вызывало взрывообразный рост трафика в сети и могло привести к переполнению, в результате которого часть сегментов отбрасывалась и требовалась повторная передача.
Алгоритм, направленный на избежание подобной ситуации, получил название медленного старта (slow start). Основная идея, лежащая в основе этого алгоритма, заключается в том, что на начальном этапе передачи сегменты должны отправляться со скоростью, пропорциональной скорости получения подтверждений.
Реализация этого алгоритма предусматривает использование дополнительного к рассмотренным ранее окна отправителя — окна переполнения (congestion window). При установлении связи с адресатом значение этого окна cwnd
устанавливается равным одному сегменту (значению MSS, анонсированному адресатом, или некоторому значению по умолчанию, обычно 536 или 512 байтов). При вычислении доступного окна отправитель использует меньшее из предлагаемого окна и окна переполнения. Каждый раз, когда отправитель получает подтверждение полученного сегмента, его окно переполнения увеличивается на величину этого сегмента.
Легко заметить, что предлагаемое окно служит для управления потоком со стороны получателя, в то время как окно переполнения служит для управления со стороны отправителя. Если первое из них связано с наличием свободного места в буфере приема адресата, то второе — с представлением о загрузке сети у отправителя данных.
Обычно предлагаемое окно больше одного сегмента, поэтому отправитель передает один сегмент и ожидает подтверждения. Когда подтверждение приходит, он увеличивает значение окна переполнения до двух сегментов, таким образом, два сегмента разрешены к передаче. После того как получение каждого из этих сегментов подтверждено, размер окна переполнения становится равным четырем сегментам. Можно показать, что по мере отправления сегментов и получения подтверждений размер окна переполнения растет экспоненциально, соответственно растет и эффективная скорость передачи. [76] Легко вывести формулу изменения размера окна, предполагая, что время передачи данных от отправителя к получателю и обратно (Round Trip Time, RTT) гораздо больше времени передачи сегмента отправителем. Здесь параметр sz равен размеру сегмента (например, MSS): cwnd 0 = sz cwnd 1 = cwnd 0 + (cwnd 0 /sz)*sz = 2*cwnd 0 ... cwnd n = 2*cwnd n-1 = 2 n *sz
Начиная с некоторого значения скорость передачи достигнет эффективной пропускной способности виртуального канала между источником и получателем, и ее дальнейший рост приведет к потере данных. Начиная с этого момента, включается механизм устранения заторов, который будет обсужден ниже.
Переполнение, или затор, может возникнуть в сети по многим причинам. Например, если данные поступают к шлюзу по высокоскоростному каналу и должны быть переданы в низкоскоростной канал. Или данные нескольких каналов мультиплексируются в один канал, пропускная способность которого меньше суммы входящих. Во всех этих случаях неизбежна потеря пакетов.
Алгоритмы, позволяющие избежать заторов, основываются на предположении, что потеря данных, вызванная ошибками передачи по физической среде, пренебрежимо мала (гораздо меньше 1%). Следовательно, потеря данных свидетельствует о заторе, произошедшем где-то на пути следования пакета. В свою очередь, о потере данных отправитель может судить по двум событиям: значительной паузе в получении подтверждения или получении дубликата(ов) подтверждения.
Хотя устранение затора и медленный старт являются независимыми механизмами, каждый из которых имеет свою цель, обычно они реализуются совместно. Для их работы необходимо два дополнительных параметра виртуального канала; [77] Для простоты мы рассматриваем несимметричный виртуальный канал, в котором данные передаются в одну сторону, а управляющие сообщения (подтверждения, обновления окна и т.д.) передаются в обратную сторону. Эти рассуждения легко могут быть распространены и на случай полнодуплексного канала, когда каждая из сторон одновременно является и получателем и отправителем данных.
окно переполнения cwnd
и порог медленного старта ssthresh
. Работа комбинированного алгоритма определяется следующим правилам:
Читать дальше