Java DatagramPacket (UDP) максимальный размер буфера отправки / получения - PullRequest
17 голосов
/ 09 февраля 2012

В Java при использовании DatagramPacket предположим, что у вас есть буфер byte[1024*1024].Если вы просто передадите это для DatagramPacket при отправке / получении, будет ли Java принимать вызов для блока DatagramPacket, пока он не прочитает весь мегабайт?

Я спрашиваю, разделит ли его Java или просто попытается отправитьвсе это отбрасывается.

Обычно ограничение размера составляет около 64 КБ для пакета UDP, но я удивляюсь, так как API Java допускает байтовые массивы, если это ограничение, и что-то сверхбольшое сбрасывается или разделяется ипересобран для вас.

Если его отбросить, какой вызов API скажет мне максимальную полезную нагрузку данных, которую я могу использовать в вызове Java?Я слышал, что IPv6 также имеет большие кадры, но поддерживает ли DatagramPacket (или DatagramSocket), что, поскольку UDP определяет спецификацию заголовка?

Ответы [ 2 ]

26 голосов
/ 11 февраля 2012

DatagramPacket - это просто оболочка для сокета на основе UDP, поэтому применяются обычные правила UDP.

64 килобайта - теоретический максимальный размер полной дейтаграммы IP, но гарантированно будет маршрутизировано только 576 байтов. На любом данном сетевом пути связь с наименьшим максимальным передающим блоком будет определять фактический предел. (1500 байт, меньше заголовков - это общий максимум, но невозможно предсказать, сколько будет заголовков, поэтому безопаснее всего ограничить сообщения до 1400 байт.)

Если вы превысите ограничение MTU, IPv4 автоматически разбьет дейтаграмму на фрагменты и в конце соберет их, но только до 64 килобайт и только если все фрагменты пройдут. Если какой-либо фрагмент потерян или какое-либо устройство решит, что ему не нравятся фрагменты, то весь пакет будет потерян.

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

Что касается ошибок, если вы попытаетесь отправить больше байтов, чем разрешено ОС, вы должны получить ошибку EMSGSIZE или ее эквивалент. Если вы отправите меньше этого, но больше, чем позволяет сеть, пакет просто исчезнет.

0 голосов
/ 04 октября 2013

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

В продолжение вашего ответа о размере MTU, в моей практике я пытаюсь использовать NetworkInterface.getMTU()-40 для установки размера буфера DatagramSocket.setSendBufferSize().Таким образом, стараясь не полагаться на getSendBufferSize() Это делается для того, чтобы убедиться, что оно соответствует разным размерам окон на разных платформах и универсально приемлемо для Ethernet (на мгновение игнорируя модем).Я не жестко запрограммировал его на 1460 байт (1500-20-20), потому что в Windows размер MTU обычно равен 1500. Однако собственный размер окна платформы Windows составляет 8192 байта, но я считаю, что установив SO_SNDBUF в значение

Аналогично, для буфера приема я использую максимум 64K или 65535 байтов.Таким образом, моя программа переносима на разные платформы, используя окна разных размеров.

Как вы думаете, это звучит нормально?Я не реализовывал никаких инструментов для измерения каких-либо различий, но предполагал, что это основано на том, что там есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...