Когда сетевой пакет TCP будет фрагментирован на прикладном уровне?

StackOverflow https://stackoverflow.com/questions/756765

  •  09-09-2019
  •  | 
  •  

Вопрос

Когда TCP-пакет будет фрагментирован на прикладном уровне?Когда TCP-пакет отправляется из приложения, получит ли получатель на прикладном уровне когда-либо пакет в двух или более пакетах?Если да, то какие условия приводят к разделению пакета.Похоже, что пакет не будет фрагментирован до тех пор, пока не достигнет предела Ethernet (на сетевом уровне) в 1500 байт.Но эта фрагментация будет прозрачна для получателя на прикладном уровне, поскольку сетевой уровень соберет фрагменты перед отправкой пакета на следующий уровень, верно?

Это было полезно?

Решение

Он будет разделен, когда достигнет сетевого устройства с меньшим MTU, чем размер пакета.Большинство сетевых устройств имеют номер 1500, но часто он может быть меньше, 1492, если этот Ethernet использует PPPoE (DSL) из-за дополнительной информации о маршрутизации, и даже меньше, если добавляется второй уровень, например общий доступ к подключению к Интернету Windows.А дозвон обычно 576!

В целом, хотя вы должны помнить, что TCP не является пакетным протоколом.Он использует пакеты на самом низком уровне для передачи по IP, но что касается интерфейса для любого стека TCP, это потоковый протокол, и он не требует предоставления вам отношения 1: 1 к отправленным или полученным физическим пакетам. (например, большинство стеков будут хранить сообщения до истечения определенного периода времени или до тех пор, пока не будет достаточно сообщений, чтобы максимизировать размер IP-пакета для данного MTU)

Например, если вы отправили два «пакета» (вызовите функцию отправки дважды), принимающая программа может получить только 1 «пакет» (принимающий стек TCP может объединить их вместе).Если вы реализуете протокол типа сообщения через TCP, вам следует включить заголовок в начале каждого сообщения (или какой-либо другой механизм верхнего/нижнего колонтитула), чтобы принимающая сторона могла разделить поток TCP обратно на отдельные сообщения, либо когда сообщение принимается двумя частями или когда несколько сообщений принимаются как блок.

Другие советы

Фрагментация должна быть прозрачной для TCP-приложения.Имейте в виду, что TCP — это потоковый протокол:вы получаете поток данных, а не пакеты!Если вы создаете свое приложение на основе идеи полных пакетов данных, у вас возникнут проблемы, если вы не добавите уровень абстракции для сборки целых пакетов из потока и последующей передачи пакетов приложению.

В вопросе делается предположение, которое неверно - TCP не доставляет пакеты своим конечным точкам, скорее, он отправляет поток байтов (октетов).Если приложение записывает две строки в TCP, оно может быть доставлено в виде одной строки на другом конце;аналогично, одна строка может быть передана в виде двух (или более) строк на другом конце.

RFC 793, Раздел 1.5:

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

Ключевыми словами являются непрерывный поток октетов (байты).

RFC 793, Раздел 2.8:

"Нет необходимой взаимосвязи между функциями push и границами сегмента .Данные в любом конкретном сегменте могут быть результатом одного ОТПРАВИТЬ вызов, полностью или частично, или из нескольких отправленных вызовов. "

Весь раздел 2.8 имеет отношение к делу.

На прикладном уровне существует множество причин, по которым все 1500 байтов могут не отображаться при одном чтении.Различные факторы во внутренней операционной системе и стеке TCP могут привести к тому, что приложение получит некоторые байты за один вызов чтения, а некоторые — за следующий.Да, стек TCP должен заново собрать пакет перед его отправкой, но это не означает, что ваше приложение получит все это за один раз (Вероятно, оно получит его за одно чтение, но это не ГАРАНТИРОВАНО). получить это за одно прочтение).

TCP пытается гарантировать правильную доставку байтов, при этом проверка ошибок, автоматическая повторная отправка и т. д. происходят за вашей спиной.Думайте об этом как о канале на уровне приложения и не слишком углубляйтесь в то, как стек на самом деле отправляет данные по сети.

Если пакет превышает максимальный МТУ сетевого устройства он будет разбит на несколько пакетов.(Обратите внимание, что для большинства оборудования установлено значение 1500 байт, но это не обязательно.)

Реконструкция пакета должна быть полностью прозрачной для приложений.

Различные сегменты сети могут иметь разные значения MTU.В этом случае может произойти фрагментация.Для получения дополнительной информации см. TCP Максимальный размер сегмента

Эта (де)фрагментация происходит на уровне TCP.На прикладном уровне пакетов больше нет.TCP предоставляет приложению непрерывный поток данных.

«Прикладной уровень» — TCP-пакет (ну, на самом деле сегмент;TCP на своем собственном уровне не знает пакетов) никогда не фрагментируется, поскольку его не существует.На уровне приложений вы видите данные как поток байтов, доставляемых надежно и в порядке.

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

Этот Страница является хорошим источником информации о некоторых проблемах, поднятых другими, а именно о необходимости инкапсуляции данных для каждого протокола приложения на основе протокола приложения. Не совсем авторитетный в том смысле, который вы описываете, но на нем есть примеры, и он получен некоторыми симпатичными громкие имена в сетевом программировании.

Правильно: наиболее информативный способ увидеть это — использовать Вайршарк, бесценный инструмент.Потратьте время, чтобы разобраться в этом - несколько раз спас меня и дает хорошую проверку реальности.

Если пакет размером 3000 байт поступает в сеть Ethernet с размером MTU по умолчанию 1500 (для Ethernet), он будет фрагментирован на два пакета по 1500 байт каждый.Это единственный раз, о котором я могу думать.

Wireshark — лучший способ проверить это.Я использую его некоторое время и полностью впечатлен

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top