Там утверждается, что "окно" увеличивается в 10 раз, при передаче текстовых данных.
Проведя эксперимент, указанный в статье:
$ sudo ss -ti
получаю: ...cwnd:10...
Это объясняет ситуацию, почему для блоков текстовых данных — я видел порог в районе 14 KBytes,
а при обмене сериализованными данными — на порядок (да — именно в 10 раз) меньше!
Окно и размер IP пакета это никак не связанные вещи. Размер TCP окна это сколько данных один компьютер может переслать другому без подтверждения доставки. Если это 14 килобайтов, а в IP пакет влезает 1 килобайт, значит один компьютер отправит другому 14 IP пакетов с данными. Если к этому времени не придёт подтверждения, то передача следующих пакетов приостановится. Чем больше размер TCP окна, тем больше скорость (пока не упрётся в ширину канала), но тем больше данных нужно держать локально (т.к. если подтверждение не придёт, придётся их посылать ещё раз).
Здравствуйте, AlexGin, Вы писали:
AG>Это объясняет ситуацию, почему для блоков текстовых данных — я видел порог в районе 14 KBytes, AG>а при обмене сериализованными данными — на порядок (да — именно в 10 раз) меньше!
Здравствуйте, vsb, Вы писали:
vsb>Окно и размер IP пакета это никак не связанные вещи.
Хорошо — максимально допустимый размер блока (пользовательского_пакета) передаваемого "одним_целым_куском" прямо пропорционален размуру окна — так корректнее.
Здесь подразумевается, что этот блок также целиком (без дробления на фрагменты) поступит в точку приёма.
vsb>Размер TCP окна это сколько данных один компьютер может переслать другому без подтверждения доставки. Если это 14 килобайтов, а в IP пакет влезает 1 килобайт, значит один компьютер отправит другому 14 IP пакетов с данными.
+100500
Я говорю о том же самом, только другими словами.
vsb>Если к этому времени не придёт подтверждения, то передача следующих пакетов приостановится.
Логично.
vsb>Чем больше размер TCP окна, тем больше скорость (пока не упрётся в ширину канала), но тем больше данных нужно держать локально (т.к. если подтверждение не придёт, придётся их посылать ещё раз).
Хорошо, значит мы вернулись к первоначальному:
Размер (объём) блока прямо пропорционален ширине окна.
Если окно для текстовых данных в 10 раз шире, чем для произвольных двоичных, то и размер блока примерно в десять раз больше для этого случая!
Именно этот факт я и наблюдал при моих экспериментах.
P.S. Идея понятна, а также понятно почему появляется различие в 10 раз!
Здравствуйте, AlexGin, Вы писали:
AG>Там утверждается, что "окно" увеличивается в 10 раз, при передаче текстовых данных.
Окно — это не про размер пакетов, а про то, сколько байт может передать передатчик (байт, а не пакетов, не важно, каким количеством пакетов они уйдут), не дожидаясь подтверждения от приемника, что можно еще слать.
AG>Это объясняет ситуацию, почему для блоков текстовых данных — я видел порог в районе 14 KBytes, AG>а при обмене сериализованными данными — на порядок (да — именно в 10 раз) меньше!
Для TCP нет никакой разницы между текстовыми и бинарными данными. Для Ethernet'а ее тоже нет. Никто из них не занимается компрессией данных.
Здравствуйте, AlexGin, Вы писали:
AG>При MTU 1500 байт, а если учесть длину заголовка, то получим порядка 1400 байт.
AG>Но я помнил, что где-то читал насчёт значения равного 14 килобайт. AG>Удивительное расхождение — в 10 раз!
Jumbo-кадр (англ. jumbo frame) — понятие в компьютерных сетях, обозначающее кадр сети Ethernet, в котором, можно передать данные, по размеру превышающие 1500 байт, заданные стандартами группы IEEE 802.3 (MTU более 1500 байт)[1]. Традиционно jumbo-кадры могут передавать до 9000 байтов данных, но существуют другие варианты и требуется обращать внимание на совместимость между различными сетевыми устройствами и их настройки.
An optional feature of IPv6, the jumbo payload option, allows the exchange of packets with payloads of up to one byte less than 4 GiB (232 − 1 = 4,294,967,295 bytes), by making use of a 32-bit length field.
MD>Jumbo-кадр (англ. jumbo frame) — понятие в компьютерных сетях, обозначающее кадр сети Ethernet, в котором, можно передать данные, по размеру превышающие 1500 байт, заданные стандартами группы IEEE 802.3 (MTU более 1500 байт)[1]. Традиционно jumbo-кадры могут передавать до 9000 байтов данных, но существуют другие варианты и требуется обращать внимание на совместимость между различными сетевыми устройствами и их настройки.
MD>An optional feature of IPv6, the jumbo payload option, allows the exchange of packets with payloads of up to one byte less than 4 GiB (232 − 1 = 4,294,967,295 bytes), by making use of a 32-bit length field.
Это совсем другое.
По размеру кадров — отличия может и не быть.
Здравствуйте, AlexGin, Вы писали:
AG>Доброго времени суток, уважаемые коллеги!
AG>У меня (да и похоже не только у меня) в процессе обсуждения максимального блока данных протокола TCP возник резонный вопрос:
Тебе лучше книги почитать на ночь вроде Дуглас Камер. Сети TCP/IP, том 1. Принципы, протоколы и структура, и второй том. Как вариант, rfc793 и спопутствующие.
vsb>>Окно и размер IP пакета это никак не связанные вещи. AG>Хорошо — максимально допустимый размер блока (пользовательского_пакета) передаваемого "одним_целым_куском"
В тцп нет никаких пользовательских пакетов, можно сделать send(buf, 1024*1024) и потом recv ом принять посланные данные по одному байтику, или по два, или по 10, или до 1000, или даже если "повезет" одним мегабайтов.
Забудь про слово 'пакет' когда работаешь с тцп. Про него нужно вспоминать только при низкоуровневом тюнинге перфоманса или решении специфиеских проблем типа PMTU blackhole.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, уважаемый Pzz, Вы писали:
Pzz>Окно — это не про размер пакетов, а про то, сколько байт может передать передатчик (байт, а не пакетов, не важно, каким количеством пакетов они уйдут), не дожидаясь подтверждения от приемника, что можно еще слать.
+100500
Ну так это — как раз в тему!
Значит, если мы говорим о блоке данных, то увеличение окна — уменьшает фрагментирование этого блока. Вполне логично.
При достаточной ширине окна — на приёме фрагментирования не будет — бесь блок поступит целиком (одним куском)!
AG>>Это объясняет ситуацию, почему для блоков текстовых данных — я видел порог в районе 14 KBytes, AG>>а при обмене сериализованными данными — на порядок (да — именно в 10 раз) меньше!
Pzz>Для TCP нет никакой разницы между текстовыми и бинарными данными.
Хорошо, в статье: https://tylercipriani.com/blog/2016/09/25/the-14kb-in-the-tcp-initial-window
приводится факт увеличения окна, для HTTP — когда передаются текстовые (гипертокстовые) данные.
Значит, при текстовых данных, я могу воспользоваться "окном" в десять раз шире?
Что и подтверждается моими экспериментами на Ubuntu 18.04!
До Windows 10 руки дойдут в ближайшие дни.
Но я НЕ УВЕРЕН, что это стабильно будет повторяться для разных комбинаций сетевого железа и для разных OS.
Pzz>Для Ethernet'а ее тоже нет. Никто из них не занимается компрессией данных.
Здесь ИМХО вопрос не в компрессии данных, а в выборе режимов работы TCP протокола.
Pzz>>Окно — это не про размер пакетов, а про то, сколько байт может передать передатчик (байт, а не пакетов, не важно, каким количеством пакетов они уйдут), не дожидаясь подтверждения от приемника, что можно еще слать. AG>+100500 AG>Ну так это — как раз в тему!
В точку, да не в ту.
AG>Значит, если мы говорим о блоке данных, то увеличение окна — уменьшает фрагментирование этого блока. Вполне логично.
Давай начнем с определения что в твоем понимании 'блок' и что такое 'фрагментирование блока'?
AG>При достаточной ширине окна — на приёме фрагментирования не будет — бесь блок поступит целиком (одним куском)!
recv за раз может принять данные как больше чем текущий размер окна так и меньше. Есть еще куча факторов, которые влияют на то, сколько recv тебе вернет за раз. Размер tcp окна тут как раз не должен быть релевантен (хотя какая нить конкретная реализация тцп может и учитывать его каким то образом при внутренней буферизации данных) Самым лучшим будет постулировать что они тебе не подконтрольны (если только не написал свой сетевой стек, от tcp то железа).
Как много веселых ребят, и все делают велосипед...
Здравствуйте, AlexGin, Вы писали:
Pzz>>Окно — это не про размер пакетов, а про то, сколько байт может передать передатчик (байт, а не пакетов, не важно, каким количеством пакетов они уйдут), не дожидаясь подтверждения от приемника, что можно еще слать. AG>+100500 AG>Ну так это — как раз в тему! AG>Значит, если мы говорим о блоке данных, то увеличение окна — уменьшает фрагментирование этого блока. Вполне логично. AG>При достаточной ширине окна — на приёме фрагментирования не будет — бесь блок поступит целиком (одним куском)!
Будет фрагментирование, будет. Никаким одни куском блок не поступит.
Здравствуйте, Marty, Вы писали:
M>Неясна связь с типом данных
+100500
Да, теоретически — вроде как её и не должно быть, как я понял изучая литературу по TCP.
Но практика, когда дробление на фрагменты начинается от 14 килобайт — для английских однобайтовых символов (когда передаём только JSON-текст);
и примерно от 1400 байт — для потока двоичных сериализованных данных.
О чём говорит?
Есть предположение, что софт поддержки TCP всё-же анализирует контент в канале (хотя бы на соответствие KOI8 или Latin1).
P.S. Приведу цифры, полученные при передаче JSON блоков данных на сети от Сервера к Клиенту
(они на разных компах, соединены витой парой; на обоих машинах OS Ubuntu 18.04):
LEN (длина блока, байт) Факт разделения блока на фпагменты
____________________________________________________________________
18494 +
14512 +
13911 иногда имело место
27148 +
14243 +
7727 -
Здесь ясно видно, что JSON блок в 7 килобайт проходит без разделения на фрагменты. Как объснить данный феномен (при MTU = 1500)?
Для упрощения можешь представить себе следующую модель (это только модель, а не достоверная реализация!):
Есть сокет, у сокета есть внутренний кольцевой буфер определенного размера. Когда ты делаешь send — данные в этот буфер просто копируются, двигая голову буфера.
Где то в операционке крутится фоновый поток, который данные из этого буфера выгребает и посылает. Он в курсе про MTU, знает про текущий TCP Window size, оптимизирует запросы с учетом размера страниц памяти, учитывает фазу Луны и текущее время года. Единственное что он точно не учитывает — какую там циферку указал в аргументах пользователь последнего send-а.
С recv'ом все тоже самое. тцп пакет с данными приходит — операционка определяет к какому сокету он относится и _добавляет_ его в буфер приема того сокета. И так каждый раз.
Когда именно раздуплится поток, который вызывает recv и какая то часть данных из этого буфера будет ему выдана на-гора — зависит примерно от тех же факторов, что описаны сверху.
Так что никаких гарантий о том что ты послал килобайт и тебе этот килобайт придет целиком нету и быть не может. Как нету гарантий того что ты послал два раза по 512 байт а они тебе не придут одним килобайтным куском. Или тремя кусками разных размеров.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, Marty, Вы писали:
... M>Будет фрагментирование, будет. Никаким одни куском блок не поступит.
Я не спорю — фрагментируется!
И далее — я его собираю из сегментов.
Порог (когда начинается фрагментирование) где-то в районе 1400 байт. Здесь ничто не противоречит теории.
Но...
Есть одно но — это характерно только для текстовых JSON данных — порог увеличивается в десять раз.
M>Ты какую-то ерунду несеш
Эйнштейн и Коперник — в своё время также несли ерунду
AG>Порог (когда начинается фрагментирование) где-то в районе 1400 байт. Здесь ничто не противоречит теории. AG>Но... AG>Есть одно но — это характерно только для текстовых JSON данных — порог увеличивается в десять раз.
У тебя инет случайно не через VPN? У всяких там туннелей может применяться компрессия траффика.
Второй вариант — именно при приеме json твой код работает медленней, реже вызывая recv, изза чего в приемном буфере сокета скапливается больше гданных.
Как много веселых ребят, и все делают велосипед...
Здравствуйте, AlexGin, Вы писали:
AG>Но практика, когда дробление на фрагменты начинается от 14 килобайт — для английских однобайтовых символов (когда передаём только JSON-текст); AG>и примерно от 1400 байт — для потока двоичных сериализованных данных. AG>О чём говорит?
Я не могу понять, о каком дроблении на фрагменты вообще идёт речь? Давай начнем с того, что ты объяснишь свою терминологию
AG>Есть предположение, что софт поддержки TCP всё-же анализирует контент в канале (хотя бы на соответствие KOI8 или Latin1).
Что значит "софт поддержки TCP"?
Линуксовая реализация стека TCP? Может, сразу в код посмотреть?
Но вообще, звучит как чушь
AG>P.S. Приведу цифры, полученные при передаче JSON блоков данных на сети от Сервера к Клиенту AG>(они на разных компах, соединены витой парой; на обоих машинах OS Ubuntu 18.04): AG>... AG>Здесь ясно видно, что JSON блок в 7 килобайт проходит без разделения на фрагменты. Как объснить данный феномен (при MTU = 1500)?
Здесь ничего не видно. Без кода это вообще цифры с потолка. Сколько раз эксперимент повторялся?
Здравствуйте, AlexGin, Вы писали:
M>>Будет фрагментирование, будет. Никаким одни куском блок не поступит.
AG>Я не спорю — фрагментируется! AG>И далее — я его собираю из сегментов.
Не понял, как ты его собираешь? Ты стек TCP пишекшь, что ли?
M>>Ты какую-то ерунду несеш AG> AG>Эйнштейн и Коперник — в своё время также несли ерунду
Ты не Эйнштейн или Коперник. Ты какую-то телегонию несешь
Здравствуйте, AlexGin, Вы писали:
AG>Значит, если мы говорим о блоке данных, то увеличение окна — уменьшает фрагментирование этого блока. Вполне логично. AG>При достаточной ширине окна — на приёме фрагментирования не будет — бесь блок поступит целиком (одним куском)!
Нет, не уменьшает. Как только придет первых пакет из пачки, если есть подходящий read(), он его и получит, не дожидаясь остальных.
AG>>>Это объясняет ситуацию, почему для блоков текстовых данных — я видел порог в районе 14 KBytes, AG>>>а при обмене сериализованными данными — на порядок (да — именно в 10 раз) меньше!
AG>https://tylercipriani.com/blog/2016/09/25/the-14kb-in-the-tcp-initial-window AG>приводится факт увеличения окна, для HTTP — когда передаются текстовые (гипертокстовые) данные.
Человек изучал контретную проблему — отдачу по HTTP, поэтому и данные у него тестовые. Если бы он занимался отдачей медицинских анализов по специальному медицинскому протоколу, результаты были бы точно такие же, а ты писал бы в форум, что анализы кала и мочи ходят с окном в 10 раз больше, чем обычные бинарные данные.
Еще раз (и, наверное, последний, я устал повторять одно и то же), TCP все равно, что передавать, текстовые данные, бинарные данные, последовательность нулей, псевдослучайную последовательность, результаты анализов кала и мочи.
AG>Значит, при текстовых данных, я могу воспользоваться "окном" в десять раз шире? AG>Что и подтверждается моими экспериментами на Ubuntu 18.04!
В твоих экспериментах есть какая-то методологическая ошибка. Иначе ты не получил бы неверных результатов.
AG>Здесь ИМХО вопрос не в компрессии данных, а в выборе режимов работы TCP протокола.
У TCP протокола нет специального режима для текстовых данных.
Здравствуйте, AlexGin, Вы писали:
AG>Но практика, когда дробление на фрагменты начинается от 14 килобайт — для английских однобайтовых символов (когда передаём только JSON-текст); AG>и примерно от 1400 байт — для потока двоичных сериализованных данных. AG>О чём говорит?
О методологической ошибке в твоем эксперименте.
AG>Есть предположение, что софт поддержки TCP всё-же анализирует контент в канале (хотя бы на соответствие KOI8 или Latin1).
Не анализирует. Я этот "софт поддержки TCP" внимательно читал, в отличии от тебя. И даже писал, но не для линуха. И очень хорошо знаю, как он устроен.