Перейти к содержанию
    

TCP Delayed ACK Понимание принципа

Приветствую. 

Собственно вопрос, как работает данный принцип и что нужно для его реализации.

Например, требуется передать данные больше, чем MTU, соответственно их разбиваем на N пакетов, по размеру не превышающих win приемника, дальше их можем передавать без получения подтверждения от приемника. Минимум нужно передать 2 пакета, чтобы не попасть на 200мсек задержку подтверждения.

Что не понятно - по всяким номерам последовательностей. На сколь понял их два, приемника и передатчика. После начала соединения (приема SYN) происходит начальное установление номера ISS. Далее каждый пакет при приеме ACK должен увеличивать на 1, но если передаем без ACK, то что с этим номером делать? Может кто объяснить более понятно, как вообще должно все это дело функционировать?

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

Delayed ACK говорит вам  что  вы можете отправлять ACK не сразу по приходу  пакета, а с некой задержкой  в расчете на то что если за время этой задержки придут еще пакеты  то можно будет отправить всего один ACK сразу на все.  Обычно кроме параметра максимальной задержки есть еще и параметр максимального числа  полученных пакетов после которого надо обязательно отправить ACK.  

2 hours ago, mantech said:

Далее каждый пакет при приеме ACK должен увеличивать на 1

Не путайте номера  последовательности байтов SEQ|ACK  и  число посланных  пакетов  в алгоритме congestion window.
Значение SEQ  указывает на позицию первого байта в пакете и меняется на число посланных байт в пакете. А число всегда ACK указывает на позицию следующую за последним корректно принятый байтом (то есть ожидаемого следующего SEQ).   

 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

32 минуты назад, RobFPGA сказал:

Не путайте номера  последовательности байтов SEQ|ACK  и  число посланных  пакетов  в алгоритме congestion window.

 

32 минуты назад, RobFPGA сказал:

в расчете на то что если за время этой задержки придут еще пакеты  то можно будет отправить всего один ACK сразу на все. 

Вот про это и просил рассказать по-подробнее. В гугле и виках об этом вскользь или вообще никак, а путаницы тут хватает....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

17 minutes ago, mantech said:

Вот про это и просил рассказать по-подробнее. В гугле и виках об этом вскользь или вообще никак, а путаницы тут хватает....

А что тут рассказывать -  есть  таймер  и есть счетчик  числа принятых но неподтверждённых пакетов (на которые не отправлен ACK).
Если  счетчик неподтверждённых пакетов ==0  таймер сброшен.  Пришел очередной пакет - счетчик +=1, таймер начал тикать :bomb:.  Если до тикал до заданной задержки  или пока тикает пришло еще несколько пакетов  и счетчик пакетов стал равен заданному порогу - то  отправляем ACK с актуальной позицией принятых байт, счетчик сбрасываем, таймер тормозим.    

В продвинутых реализациях  задержку и порог счетчика могут динамически регулировать в зависимости от параметров и состояния линка. 

 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, RobFPGA сказал:

А что тут рассказывать

Чет еще сильнее запутался...

Попробую еще раз - в заголовке есть поля Порядковый номер, Sequence Number (SN)

и Номер подтверждения, Acknowledgment Number (ACK SN)

В режиме пакет-ответ работает по такому принципу, передаю пакет с номером N, получаю аск с номером N+1. Но если аск  получать только после 2, 3... пакетов, что нужно делать с этими номерами в отправляемых пакетах?

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

20 minutes ago, mantech said:

Попробую еще раз - в заголовке есть поля Порядковый номер, Sequence Number (SN)

и Номер подтверждения, Acknowledgment Number (ACK SN)

В режиме пакет-ответ работает по такому принципу, передаю пакет с номером N, получаю аск с номером N+1. Но если аск не получать, что нужно делать с этими номерами?

Ну что ж  еще раз ... 

Номер SEQ (SN по вашему)  увеличивается на число байт  (LEN) переданных в пакете 

Вы - посылаете  пакет   с SEQ=1  и длинной LEN=10 байт - в ответ (через  время равное величине задержки ACK)  вы получите пакет с ACK==11 (SEQ+LEN)

Теперь вы посылаете  быстро 3 пакета один за другим : SEQ=11  LEN2=10,  SEQ=21 LEN=20,  SEQ=41 LEN=40   и в ответ  (если все пакеты были приняты без ошибок) вы получите задержанный ACK=81  (последний ACK + 10+20+40)  сразу подтверждающий все 3 принятых пакета. 

 

Удачи! Rob.   

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, RobFPGA сказал:

SEQ=11  LEN2=10,  SEQ=21 LEN=20,  SEQ=41

А, точно, забыл про добавление длины)))  Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, RobFPGA сказал:

и есть счетчик  числа принятых но неподтверждённых пакетов (на которые не отправлен ACK).

Если  счетчик неподтверждённых пакетов ==0  таймер сброшен.  Пришел очередной пакет - счетчик +=1, таймер начал тикать :bomb:.

TCP - байт-ориентированный протокол. Не надо там никаких пакетов. Все позиции нужно считать в байтах!

И счётчики неподтверждённого - тоже в байтах.

А то как будете выкручиваться если пришёл пакет с SEQ=100, а за ним - с SEQ=50. На полпакета назад счётчик откатывать? :biggrin:

1 час назад, mantech сказал:

В режиме пакет-ответ работает по такому принципу, передаю пакет с номером N, получаю аск с номером N+1. Но если аск  получать только после 2, 3... пакетов, что нужно делать с этими номерами в отправляемых пакетах?

Забывайте о неких "номерах пакетов". Нет таких в TCP!

1 час назад, RobFPGA сказал:

Теперь вы посылаете  быстро 3 пакета один за другим : SEQ=11  LEN2=10,  SEQ=21 LEN=20,  SEQ=41 LEN=40   и в ответ  (если все пакеты были приняты без ошибок) вы получите задержанный ACK=81  (последний ACK + 10+20+40)  сразу подтверждающий все 3 принятых пакета.

В ответ можно получить любое значение ACK в диапазоне от последнего_принятого_значения_ACK до последнее_принятое_значение_ACK+суммарная_переданная_длина. И это всё - норма. Алгоритм должен это учитывать.

Т.е. - если последний принятый ACK был==11, то новый ACK может быть любым в диапазоне == 11...81. Если за пределами этого диапазона - ошибка и сброс соединения (если ACK - больше), и игнор (если ACK - меньше).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 минут назад, jcxz сказал:

Забывайте о неких "номерах пакетов". Нет таких в TCP!

Мне так для понимания удобнее, считать в пакетах от 0 до MTU. Если б там не было ограничения в MTU, т.е. я мог бы передать за раз сразу столько, сколько надо, тогда да - байт-организованность была б удобнее, ИМХО :biggrin:

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, mantech сказал:

Мне так для понимания удобнее, считать в пакетах от 0 до MTU.:biggrin:

Другой стороне фиолетово на ваши MTU. Она может пол-MTU прислать или четверть - как будет ей удобнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, jcxz сказал:

Она может пол-MTU прислать или четверть - как будет ей удобнее.

Эт понятно и учитывается, но фат в том, что больше MTU, она не пришлет за 1 пакет, разумеется...

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, mantech сказал:

Эт понятно и учитывается, но фат в том, что больше MTU, она не пришлет...

Это почему? Может хоть 10 MTU прислать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, jcxz сказал:

Это почему? Может хоть 10 MTU прислать.

Может и 20, но это будут отдельные пакеты, длиной не больше MTU. Почему тут и разница в понимании, протокол-байт-ориентированный, а интерфейс пакетно-ориентированный...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 минут назад, mantech сказал:

Может и 20, но это будут отдельные пакеты, длиной не больше MTU. Почему тут и разница в понимании, протокол-байт-ориентированный, а интерфейс пакетно-ориентированный...

Мы говорим об ACK. Который удалённая сторона присылает на SEQ вашей стороны. И удалённая сторона может сколько угодно пакетов слать с ACK==11 (не подтверждая приём ни одного отправленного вами байта), а потом в одном пакете - сразу ACK=81, подтвердив таким образом сразу все отправленные вашей стороной данные.

Это уж не говоря о том, что от удалённой стороны могут приходить и ACK=10 и ACK=9 ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

4 hours ago, jcxz said:

TCP - байт-ориентированный протокол. Не надо там никаких пакетов. Все позиции нужно считать в байтах!

И счётчики неподтверждённого - тоже в байтах.

А то как будете выкручиваться если пришёл пакет с SEQ=100, а за ним - с SEQ=50. На полпакета назад счётчик откатывать? :biggrin:

А ни как -  я ведь говорил про  пришедшие и корректно принятые пакеты, а пакеты с некорректным SEQ (который не соответствую ожидаемому) принятыми не считаются.  Такие пакеты  либо ждут своего часа в буфере либо, как в вашем примере, отбрасываются с генерацией DUP_ACK пакета при необходимости. 

 

4 hours ago, jcxz said:

В ответ можно получить любое значение ACK в диапазоне от последнего_принятого_значения_ACK до последнее_принятое_значение_ACK+суммарная_переданная_длина. И это всё - норма. Алгоритм должен это учитывать.

Т.е. - если последний принятый ACK был==11, то новый ACK может быть любым в диапазоне == 11...81. Если за пределами этого диапазона - ошибка и сброс соединения (если ACK - больше), и игнор (если ACK - меньше).

Послать  можно что угодно и куда угодно :unknw:,  но мне не попадались реализации стека в которых было бы произвольное (а не по границе принятых пакетов) значение ACK. Такая реализация  (с произвольным ACK) создает кучу проблем  без всякого профита. 

3 hours ago, jcxz said:

Это уж не говоря о том, что от удалённой стороны могут приходить и ACK=10 и ACK=9 .

Единственная валидная ситуация когда обрабатывается пакет с ACK  меньше чем последний полученный ACK - это пакеты keep-alive (для поддержания соединения).  При этом посылается значение  ACK-1;

4 hours ago, jcxz said:

TCP - байт-ориентированный протокол. Не надо там никаких пакетов. Все позиции нужно считать в байтах!

Так и есть - для  пользователя он байт-ориентированный. Но со времени когда TCP придумали  он оброс таким количеством  изменений/дополнений  что  черт ногу сломит.  Многие алгоритмы расчета окна передачи оперируют не байтами а числом  пакетов (segments)  размером с MTU.      

 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...