Re[11]: Максимальная длина TCP пакета в сети
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.02.20 20:28
Оценка: +1
Здравствуйте, AlexGin, Вы писали:

AG>Что здесь не так?

AG>Я использовал некоторое подмножество вариантов применения TCP.
AG>Да, может возможно было бы более рационально использовать пропускную спрсобность канала.
AG>Но это не имеет актуальности.

Не надо при проектировании framing'а полагаться на то, что фреймы эти будут использоваться строго в режиме вопрос-ответ. Ничего особо не выигрываешь, а лишь смешиваешь два логически не связанных уровня. О чем потом и пожалеешь.

Я даже не о пропускной способности канала сейчас говорю, а о логической целостности твоего протокола.
Re[13]: Максимальная длина TCP пакета в сети
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.02.20 20:32
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Да, тут сложней. Решение есть, даже два. Либо websockets, либо HTTP/2. Ну или делать polling, на самом деле тоже не самый плохой вариант. Но такое сам не пробовал и это уже посложней. Моя реплика в первую очередь относилась к модели запрос/ответ. Если нужно со стороны сервера инициировать сообщения, тут уже не всё так однозначно, соглашусь.


О, так и знал, прочтя твое первое сообщение про HTTP, что дойдет и до новомодного HTTP/2

Что до вебсокета, он превращает HTTP в, практически, TCP-сокет с навешенным на него фреймингом. В терминах HTTP это называется protocol upgrade
Re[11]: Максимальная длина TCP пакета в сети
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.02.20 20:33
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>У IPv4 контрольная сумма защищает только заголовок. У IPv6 по-моему вообще её нет.


Там две контрольные суммы. Одна защищает заголовок, другая — тело TCP-пакета. И обе одинаково паршивые.
Re[2]: Максимальная длина TCP пакета в сети
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.20 20:39
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>MTU — это параметр сетевого интерфейса, который определяет максимальный размер пакета (все равно какого, TCP, UDP, ICMP...), который не будет фрагментироваться при отправке через этот интерфейс.


Для TCP важен минимальный из всех MTU по дороге.

Pzz>TCP, естественно, не хочет, чтобы его пакеты фрагментировались. Поэтому при соединении по локальной сети TCP будет ориентироваться на MTU, за вычетом служебных данных. А вот если соединение нелокальное, то у TCP нет знаний о том, как будет происходить фрагментация на промежуточных узках. Поэтому он будет исходить из максимального размера пакета, доставка которого без фрагментации гарантируется IP-протоколом. А это 576 байт для IPv4, и 1280 для IPv6.


Начинает с MTU исходящего интерфейса и корректирует по поступлению ICMP needfrag сообщений. Это во всех стеках. В Linux, да, есть дополнительный режим "если та сторона не подтверждает — пробуем уменьшать размер нагрузки".
The God is real, unless declared integer.
Re[3]: Максимальная длина TCP пакета в сети
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.20 20:41
Оценка: +1
Здравствуйте, AlexGin, Вы писали:

AG>Это только в теории...

AG>Впрочем, я также думал до недавнего времени. Пока не столкнулся с ситуацией:
AG>Когда сервер и клиент — на одном и том же компе — всё работает как швейцарские часы.
AG>Но вот если сервер и клиент — соединены проводом и через хаб — как это в реальной жизни — то тут начинается практика...

В чём эта "практика"? Если вы учитываете, какими порциями смог прочитать recv() на приёмнике — вы уже успешно выстрелили себе в ногу. Не надо так.
The God is real, unless declared integer.
Re: Максимальная длина TCP пакета в сети
От: Reset  
Дата: 10.02.20 20:47
Оценка: 6 (1) +1
Я бы на твоем месте, передавал блоки данных с длинной в заголовке блока (чтобы не парсить в поисках маркера конца, кроме того, с маркером ты не сможешь передавать в данных последовательность, используемую для маркера). Про MTU и все что лежит ниже уровня TCP тебе лучше сейчас вообще забыть, т.к. оно не влияет на передачу данных твоего приложения. То, что ты когда-то не смог найти маркер конца пакета и решил, что данные были изменены по пути — скорее всего ошибка в твоем приложении. Про то, что TCP потоковый протокол, тебе уже рассказали.

В общем, передавай данные блоками с длинной в заголовке. Читай до тех пор, пока не получишь весь блок целиком (тут нужно будет обрабатывать возможность отключения клиента и, возможно, другие ошибки типа таймаута). И все будет у тебя работать, как надо.

Маркер тебе не нужен, если очень хочется проверить целостность данных — используй контрольную сумму в виде sha256 (опять же в заголовке или в хвосте данных). Еще большую надежность даст TLS, но тогда придется заморочиться с сертификатами и чуть увеличится время подключения (на 1RTT/время туда-сюда). Накладные расходы на шифрование и дополнительные копирования ничтожны, если только ты не делаешь сервер Netflix (а это точно не так).

P.S. Если захочешь разобраться с MTU и как там оно устроено на более низких уровнях — это всегда пожалуйста, спрашивай. Но сейчас для твоего прикладного протокола тебе это не надо.

P.P.S. У TCP есть включенный по умолчанию алгоритм минимизации количества пакетов (гуглить по "TCP_NODELAY"). Когда TCP пакет сформирован не целиком (записали 10 байт, например, а в TCP пакет влезает 1460, или записали 10K и в последнем пакете еще осталось место), то пакет ждет несколько ms, вдруг появятся еще данные, чтобы их тоже отправить в том же пакете (целиком сформированные пакеты пойдут в сеть сразу, им нет смысла ждать). Тебе, возможно, полезно отключить эту задержку, чтобы при записи в сеть блока данных, он тут же начал отправляться без задержки.
Re[3]: Максимальная длина TCP пакета в сети
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.02.20 20:47
Оценка:
Здравствуйте, netch80, Вы писали:

N>Начинает с MTU исходящего интерфейса и корректирует по поступлению ICMP needfrag сообщений. Это во всех стеках. В Linux, да, есть дополнительный режим "если та сторона не подтверждает — пробуем уменьшать размер нагрузки".


Я не стал рассказывать про MTU path discovery, чтобы чрезмерно не переусложнять тему.

Я где-то читал, что эти needfrag не всегда доходят и не всегда посылаются, поэтому с ними бывают всякие разные проблемы. Не помню, включен ли MTU path discovery в линухе по умолчанию, а проверять лень...
Re[12]: Максимальная длина TCP пакета в сети
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.20 20:48
Оценка: +1
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, vsb, Вы писали:


vsb>>У IPv4 контрольная сумма защищает только заголовок. У IPv6 по-моему вообще её нет.


Pzz>Там две контрольные суммы. Одна защищает заголовок, другая — тело TCP-пакета. И обе одинаково паршивые.


1. Вот та, что защищает заголовок IP-пакета, в IPv6 отменена. Осталась контрольная сумма TCP.
2. Пусть паршивые, но их ортогональность типичной контрольной сумме Ethernet (которая CRC32-CCITT) очень помогает.
The God is real, unless declared integer.
Re[2]: Максимальная длина TCP пакета в сети
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.02.20 20:51
Оценка:
Здравствуйте, Reset, Вы писали:

R>P.P.S. У TCP есть включенный по умолчанию алгоритм минимизации количества пакетов (гуглить по "TCP_NODELAY"). Когда TCP пакет сформирован не целиком (записали 10 байт, например, а в TCP пакет влезает 1460, или записали 10K и в последнем пакете еще осталось место), то пакет ждет несколько ms, вдруг появятся еще данные, чтобы их тоже отправить в том же пакете (целиком сформированные пакеты пойдут в сеть сразу, им нет смысла ждать). Тебе, возможно, полезно отключить эту задержку, чтобы при записи в сеть блока данных, он тут же начал отправляться без задержки.


Вроде бы, современные TCP-стеки понимают, что если после одного или нескольких send() сказали recv(), то можно больше и не задерживать хвост последнего пакета, все равно, пока recv() чего-нибудь не вернет, send()ов больше не будет.
Re[4]: Максимальная длина TCP пакета в сети
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.20 20:52
Оценка: 2 (1)
Здравствуйте, Pzz, Вы писали:

N>>Начинает с MTU исходящего интерфейса и корректирует по поступлению ICMP needfrag сообщений. Это во всех стеках. В Linux, да, есть дополнительный режим "если та сторона не подтверждает — пробуем уменьшать размер нагрузки".


Pzz>Я не стал рассказывать про MTU path discovery, чтобы чрезмерно не переусложнять тему.


Можно было вынести в сноску. Совсем это игнорировать нежелательно — обычно именно где-то посредине дороги и возникают туннели с урезанным MTU.

Pzz>Я где-то читал, что эти needfrag не всегда доходят и не всегда посылаются, поэтому с ними бывают всякие разные проблемы. Не помню, включен ли MTU path discovery в линухе по умолчанию, а проверять лень...


Включен. Не всегда посылаются — да, бывает, но последние лет 10 я про такое уже не слышал. Может, даже самые тупые и ленивые наконец починились...
The God is real, unless declared integer.
Re[4]: Максимальная длина TCP пакета в сети
От: AlexGin Беларусь  
Дата: 10.02.20 20:58
Оценка:
Здравствуйте, уважаемый netch80, Вы писали:

N>В чём эта "практика"? Если вы учитываете, какими порциями смог прочитать recv() на приёмнике — вы уже успешно выстрелили себе в ногу. Не надо так.


Ну хорошо — я накопил данные от первого recv(), затем следующего и т.д — пока не уяснил что блок_пользовательских_данных принят весь.
Блок_пользовательских_данных — это тот полный набор данных, что следует от сервера к клиенту.
Таким образом, если при передаче по сети его разбило на несколько частей, то я их могу "накопить" и соединить вместе.
Так нормально?
Re[12]: Максимальная длина TCP пакета в сети
От: vsb Казахстан  
Дата: 10.02.20 21:06
Оценка:
Здравствуйте, Pzz, Вы писали:

vsb>>У IPv4 контрольная сумма защищает только заголовок. У IPv6 по-моему вообще её нет.


Pzz>Там две контрольные суммы. Одна защищает заголовок, другая — тело TCP-пакета. И обе одинаково паршивые.


Где?
Re[13]: Максимальная длина TCP пакета в сети
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.02.20 21:08
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Где?


Вторая — Тут
Re[5]: Максимальная длина TCP пакета в сети
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.20 21:08
Оценка: 4 (1) +1
Здравствуйте, AlexGin, Вы писали:

N>>В чём эта "практика"? Если вы учитываете, какими порциями смог прочитать recv() на приёмнике — вы уже успешно выстрелили себе в ногу. Не надо так.


AG>Ну хорошо — я накопил данные от первого recv(), затем следующего и т.д — пока не уяснил что блок_пользовательских_данных принят весь.

AG>Блок_пользовательских_данных — это тот полный набор данных, что следует от сервера к клиенту.
AG>Таким образом, если при передаче по сети его разбило на несколько частей, то я их могу "накопить" и соединить вместе.
AG>Так нормально?

Да, так нормально.

Теперь надо решить, как определять, что передача от сервера закончилась (а для сервера — аналогично от клиента). Есть разные стили фрейминга для этого. Например, один из классических — вначале идёт длина всей посылки в двоичном виде (например, 4 байта в network order == big-endian). Но можно придумать тысячи других по вкусу.
The God is real, unless declared integer.
Re[14]: Максимальная длина TCP пакета в сети
От: vsb Казахстан  
Дата: 10.02.20 21:12
Оценка:
Здравствуйте, Pzz, Вы писали:

vsb>>Где?


Pzz>Вторая — Тут


Не так прочитал, думал, ты про то, что IP пакет защищает тело контрольной суммой. В общем я к тому, что в TCP одна контрольная сумма, а не несколько, поэтому она и вправду не стопроцентно надёжная. Насчёт транспортного протокола не знаю, с ними не сталкивался.
Re[6]: Максимальная длина TCP пакета в сети
От: vsb Казахстан  
Дата: 10.02.20 21:14
Оценка:
Здравствуйте, netch80, Вы писали:

N>Теперь надо решить, как определять, что передача от сервера закончилась (а для сервера — аналогично от клиента). Есть разные стили фрейминга для этого. Например, один из классических — вначале идёт длина всей посылки в двоичном виде (например, 4 байта в network order == big-endian). Но можно придумать тысячи других по вкусу.


Главное не забыть, что длина тоже может прийти кусками И хорошо бы её проверять, прежде чем выделять буфер указанного размера, а то придёт 4 миллиарда от шутника какого-нибудь. 4 гигабайта пока ещё ощутимый объём памяти.
Re[15]: Максимальная длина TCP пакета в сети
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.02.20 21:15
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Не так прочитал, думал, ты про то, что IP пакет защищает тело контрольной суммой. В общем я к тому, что в TCP одна контрольная сумма, а не несколько, поэтому она и вправду не стопроцентно надёжная. Насчёт транспортного протокола не знаю, с ними не сталкивался.


Ну, она CRC32. В массштабах 4-гигабайтного кино вероятность пропустить одиночную ошибку больше половины. С другой стороны, кто его качает, кино, по голому TCP?
Re[9]: Максимальная длина TCP пакета в сети
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 10.02.20 21:59
Оценка:
Здравствуйте, Pzz, Вы писали:

AG>>>Ну или же каждый разработчик прикладного ПО на_верхнем_уровне защищается от ситуации по-своему.


M>>Никто при использовании TCP в здравом уме не защищается


Pzz>Ну строго говоря, у TCP очень паршивая контрольная сумма. Если гнать большие объемы данных по шумному каналу, данные иногда будут приходить попорченными. Но ТС вряд ли именно от этого защищается.


Могу предположить, что у такого "шумного канала" есть свои механизмы контроля целостности данных, которые расположены ниже уровня IP. В противном случае, имхо, такой канал никому не нужен будет.
Так, у Ethernet'а, например, есть ещё CRC32 кадра
Маньяк Робокряк колесит по городу
Re[7]: Максимальная длина TCP пакета в сети
От: AlexGin Беларусь  
Дата: 10.02.20 22:00
Оценка:
Здравствуйте, уважаемый vsb, Вы писали:

vsb>Главное не забыть, что длина тоже может прийти кусками И хорошо бы её проверять, прежде чем выделять буфер указанного размера, а то придёт 4 миллиарда от шутника какого-нибудь. 4 гигабайта пока ещё ощутимый объём памяти.


1) Система работает в специальной сети (не общего пользования), так что шутники — курят в сторонке.
2) Под длину блока — выделяется четыре первых байта принятого массива — какой тебе кусок на менее, чем четыре байта
Re[8]: Максимальная длина TCP пакета в сети
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 10.02.20 22:09
Оценка:
Здравствуйте, AlexGin, Вы писали:

vsb>>Главное не забыть, что длина тоже может прийти кусками И хорошо бы её проверять, прежде чем выделять буфер указанного размера, а то придёт 4 миллиарда от шутника какого-нибудь. 4 гигабайта пока ещё ощутимый объём памяти.

AG>
AG>1) Система работает в специальной сети (не общего пользования), так что шутники — курят в сторонке.
AG>2) Под длину блока — выделяется четыре первых байта принятого массива — какой тебе кусок на менее, чем четыре байта

Имеется в виду вариант типа такого:
вызвали recv() — пришло, например, 1460 байт (типовой MSS на Ethernet без timestamp-опций).
Из них 1458 — первое сообщение с заголовком длины. А ещё 2 — начало заголовка длины второго сообщения.
Теперь надо эти 2 сохранить, ответ следующего recv() дописать к ним и уже тогда декодировать длину.
The God is real, unless declared integer.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.