Когда сетевой пакет TCP будет фрагментирован на прикладном уровне? - PullRequest
33 голосов
/ 16 апреля 2009

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

Ответы [ 10 ]

36 голосов
/ 16 апреля 2009

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

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

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

16 голосов
/ 16 апреля 2009

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

11 голосов
/ 21 апреля 2010

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

RFC 793 , раздел 1.5:

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

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

RFC 793 , раздел 2.8:

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

Актуален весь раздел 2.8.

5 голосов
/ 16 апреля 2009

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

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

2 голосов
/ 29 апреля 2010

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

2 голосов
/ 06 июня 2009

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

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

2 голосов
/ 16 апреля 2009

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

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

2 голосов
/ 16 апреля 2009

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

Восстановление пакета должно быть полностью прозрачным для приложений.

1 голос
/ 16 апреля 2009

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

0 голосов
/ 16 апреля 2009

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

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

...