UDP ничего не знает о MTU. Пакеты UDP могут иметь любой размер от 8 до 65535 байтов. Уровни протокола ниже UDP либо могут отправить пакет определенного размера, либо отклонят отправку этого пакета с ошибкой, если она слишком велика.
Уровень ниже UDP обычно IP, либо IPv4, либо IPv6. И IP-пакет может иметь любой размер от 20 (IPv4) / 40 (IPv6) до 65535 байтов, это столько же, сколько UDP. Однако IP поддерживает механизм, называемый фрагментацией . Если IP-пакет больше по размеру, чем тот, который может транспортировать нижний уровень, IP может разделить один пакет на несколько пакетов, называемых фрагментами. Каждый фрагмент фактически является собственным IP-пакетом (имеет собственный IP-заголовок) и также сам отправляется в пункт назначения; Задача получателя состоит в том, чтобы собрать все фрагменты и восстановить из них полный пакет перед передачей полученных данных на следующий более высокий уровень (например, UDP).
Протокол Ethernet может передавать только кадры с полезной нагрузкой от 46 до 1500 байт (есть исключения, но это выходит за рамки этого ответа). Если данные полезной нагрузки меньше 46 байтов, они дополняются до 46 байтов. Если данные полезной нагрузки превышают 1500 байт, интерфейс откажется принять их. Если это произойдет, то теперь IP-уровень решит либо фрагментировать пакет, чтобы ни один фрагмент не был длиннее 1500 байт, либо сообщить об ошибке следующему более высокому уровню, если фрагментация была отключена или запрещена для этого конкретного соединения.
Фрагментации, как правило, следует избегать, так как
- Это тратит впустую ресурсы на стороне отправителя.
- это тратит впустую ресурсы на стороне получателя.
- это увеличивает издержки протокола для того же объема данных полезной нагрузки.
- если один фрагмент потерян, весь пакет потерян.
- если один фрагмент поврежден, весь пакет будет поврежден.
- в случае повторной отправки все фрагменты должны быть повторно отправлены.
Вот почему TCP разумно принимает свой размер кадра, так что пакетам никогда не требуется IP для их фрагментации. Это можно сделать, запретив IP фрагментировать пакеты, и если IP сообщает, что пакет слишком велик для отправки, TCP уменьшает размер кадра и повторяет попытку, пока больше не сообщается об ошибке.
Для UDP, однако, это будет задачей самого приложения, поскольку UDP является «тупым» протоколом, у него нет собственной логики управления, что делает его очень гибким, быстрым и простым.
Единственный размер UDP, на который можно всегда ориентироваться, - это 576 минус 8 байтов заголовка UDP и минус 20 (v4) / 40 (v6) байтов IP, поскольку стандарт IP требует, чтобы каждый хост IP мог принимать IP-пакеты с общий размер 576 байт. Реализация вашего протокола не будет соответствовать стандарту, если он не может принимать пакеты хотя бы такого размера. Обратите внимание, однако, что стандарт не говорит 576 без фрагментации, поэтому даже пакет из 576 байтов IP может быть фрагментирован между двумя хостами.
Единственный размер пакета, который вы можете использовать для переноса без фрагментации, составляет 24 байта для IPv4 и 56 байтов для IPv6, так как наименьшие заголовки IP для фрагмента составляют 20/48 байтов (v4 / v6), а фрагмент должен иметь как минимум 4/8 байт (v4 / v6) данные полезной нагрузки. Таким образом, транспортная система ниже уровня IP, которая не может транспортировать по меньшей мере пакеты этих размеров, не может использоваться для транспортировки IP-трафика.
И прежде чем кто-либо прокомментирует, что заголовок IPv6 имеет только 40 байтов: это правильно, но, в отличие от заголовка IPv4, стандартный заголовок IPv6 не имеет полей заголовка для фрагментации. Если пакет должен быть фрагментирован, то заголовок расширения фрагментации должен быть добавлен ниже базового заголовка IPv6, и этот заголовок расширения имеет длину 8 байтов. Кроме того, в отличие от IPv4, смещения фрагментации в IPv6 подсчитываются в 8 байтах, а не в 4 байтовых единицах, таким образом, фрагмент может переносить только полезную нагрузку, кратную 8 байтов в случае IPv6.