Прием пакетов в UDP

Допустим, моя программа отправляет 1000 байт по сети (UDP). Гарантируется ли, что получатель получит 1000 байт за один "пакет"? Или, возможно, ему нужно будет выполнить несколько «прочтений», пока он не получит все сообщение? если последнее верно, как я могу гарантировать, что порядок пакетов для одного и того же сообщения не "перепутается" (по порядку), или, возможно, протокол гарантирует это?
Редактировать: то есть возможно ли, что мое сообщение будет разбито на несколько пакетов? (что, если я попытаюсь отправить сообщение размером 10000 МБ, что тогда произойдет?)


person Community    schedule 24.10.2009    source источник


Ответы (5)


Вы получите все или ничего.

Но нет особой гарантии, что вы получите пакеты ровно один раз в том порядке, в котором они были переданы; возможны потеря пакетов, переупорядочивание и (реже) дублирование.

Существует максимальный размер кадра (65 507 байт), отправка () пакетов большего размера вернет ошибку.

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

UDP-пакеты МОГУТ быть фрагментированы на несколько IP-фрагментов, но ОС отбрасывает неполный пакет. Поэтому это прозрачно для приложения.

person MarkR    schedule 24.10.2009

Получатель получит весь пакет за один вызов. Длина пакета ограничена даже в теории:

Длина 16-битное поле, указывающее длину в байтах всей дейтаграммы: заголовка и данных. Минимальная длина составляет 8 байт, так как это длина заголовка. Размер поля устанавливает теоретический предел в 65 535 байт (8 байтов заголовка + 65 527 байтов данных) для дейтаграммы UDP. Практический предел длины данных, налагаемый базовым протоколом IPv4, составляет 65 507 байт.

Однако реальный предел намного ниже, обычно можно с уверенностью предположить 512 байт. См. Каков самый большой размер безопасного пакета UDP на Интернет.

person Remus Rusanu    schedule 24.10.2009
comment
так что произойдет, если я попытаюсь отправить 1024 байта? я получу ошибку при отправке или мое сообщение будет разделено на разные пакеты? (и порядок, когда между ними соблюдаться?) - person ; 25.10.2009
comment
512 — это минимальный безопасный размер. 1024 может быть успешным. Или ошибка при отправке в лучшем случае. Хуже того, пакет будет отброшен каким-то маршрутизатором в трафике, и вы никогда об этом не узнаете. В UDP нет фрагментации и реконструкции, для этого и нужен TCP. - person Remus Rusanu; 25.10.2009
comment
Ремус: Это неправильно. Фрагментация и повторная сборка выполняются на уровне IP, а значит, применимы к UDP. При использовании UDP вы либо увидите правильно собранную дейтаграмму в том виде, в каком она была отправлена, либо вообще ничего. TCP дополнительно добавляет упорядочение и подтверждение/повторную передачу. - person caf; 26.10.2009
comment
@caf: Верно, но если вы используете сеть с потерями, вашему приложению может повезти получить половину пакетов, если вы используете фрагментированный UDP, вы потеряете даже прошедшие половину пакетов. - person Zan Lynx; 09.04.2011

UDP, в отличие от TCP, не является надежным протоколом. Он не предоставляет встроенного механизма, гарантирующего, что пакеты прибывают в правильном порядке или вообще прибывают. Тем не менее, вы можете написать свои подпрограммы отправки/получения в виде шага блокировки, где каждый раз, когда пакет отправляется, отправитель должен ждать получения ACK перед повторной отправкой. Если ACK не получен по истечении заданного тайм-аута, пакет необходимо отправить повторно. Таким образом вы гарантируете, что пакеты будут получены в правильном порядке. (Для получения дополнительной информации ознакомьтесь с RFC для протокола TFTP, в котором используется эта стратегия. .)

Наконец, если возможно, вы можете вместо этого рассмотреть возможность использования TCP.

person Charles Salvia    schedule 24.10.2009

Данные, отправляемые с использованием UDP, группируются в пакеты, поэтому, если вы отправляете x количество байтов затем, ЕСЛИ получатель получит пакет, он получит x байтов.

Однако ваши пакеты могут даже не приходить или приходить не по порядку.

person Charles    schedule 24.10.2009
comment
но возможно ли, что программа сначала увидит, что у нее есть только 500 байт, а через некоторое время получит остальные 500 байт? - person ; 25.10.2009
comment
а что если размер моего сообщения 1млн байт.. что тогда? (Благодарность) - person ; 25.10.2009
comment
Я думаю, это должно работать и с 1 миллионом; но это не рекомендуется. - person Charles; 25.10.2009
comment
Поле длины представляет собой 16-битное число, поэтому 64 КБ минус пространство для заголовков IP и UDP является жестким ограничением. - person Grumdrig; 25.10.2009
comment
так что же произойдет, когда я попытаюсь отправить сообщение большего размера? я не смогу отправить его в первую очередь? - person ; 25.10.2009
comment
Затем вы должны отправить данные несколькими пакетами; как только вы убедитесь, что вы получили все пакеты, вы можете перебрать их все и извлечь содержимое, чтобы воспроизвести исходный файл. - person Charles; 25.10.2009

С помощью UDP Lite вы можете запросить получение частично поврежденных пакетов. Это может быть полезно для видео и услуг VoIP.

person Steve-o    schedule 24.01.2010
comment
надеюсь, мы получим реализацию для Windows, чтобы ее можно было использовать в настольных приложениях для конечных пользователей. - person mbx; 22.11.2014