проект передачи файлов udp — нужна ли проверка на ошибки?

Мне поставили классическую задачу передачи файлов по UDP. На разных ресурсах я читал, что проверка пакетов на наличие ошибок (добавление CRC вместе с данными в пакеты) необходима, И UDP уже проверяет поврежденные пакеты и отбрасывает их, поэтому мне нужно беспокоиться только о повторной отправке отброшенных пакетов.

Какой из них правильный? Нужно ли вручную выполнять проверку целостности пришедших пакетов или неправильные уже отбрасываются?

Язык проекта, кстати, Java.

РЕДАКТИРОВАТЬ: Некоторые источники (учебники, Интернет) говорят, что контрольная сумма охватывает только заголовок, поэтому гарантирует правильность IP-адресов отправителя и получателя и т. д. Некоторые источники говорят, что контрольная сумма также охватывает сегмент данных. В некоторых источниках говорится, что контрольная сумма может охватывать сегмент данных, НО это необязательно и определяется операционной системой.

РЕДАКТИРОВАТЬ 2: спросил моих профессоров, и они сказали, что проверка ошибок UDP в сегменте данных не является обязательной в IPv4, по умолчанию в IPv6. Но я до сих пор не знаю, контролируется ли это программистом, ОС или другим уровнем...


person uylmz    schedule 19.02.2013    source источник


Ответы (4)


Первый факт:

UDP имеет 16-битное поле контрольной суммы, начинающееся с 40-го бита заголовка пакета. Это страдает от (по крайней мере) 2 слабостей:

  • Контрольная сумма не является обязательной, все биты, установленные в 0, определяются как «Без контрольной суммы».
  • это 16-битная контрольная сумма в строгом смысле слова, поэтому она подвержена необнаруженной порче.

Вместе это означает, что встроенная контрольная сумма UDP может быть или не быть достаточно надежной, в зависимости от вашей среды.

Второй факт:

Еще более реальной угрозой, чем повреждение данных на транспорте, является переупорядочивание потери пакетов: USP не дает никаких гарантий относительно

  • все пакеты (в конечном счете) доходят до всех
  • пакеты должны поступать в той же последовательности, что и отправлены

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

Заключение:

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

Если вы вы хотите использовать UDP для передачи файлов, вам необходимо встроить в приложение те части, которые являются неотъемлемой частью TCP, но не UDP. Однако есть поговорка, что это, скорее всего, приведет к повторной реализации TCP.

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

Рекомендации по внедрению:

Что сработало для нас, так это реализация разбитого окна: полезная нагрузка разделена на куски фиксированной и удобной длины (мы использовали 1023 байта), массив состояния из N таких кусков хранится на отправляющей и принимающей стороне.

На стороне отправки:

  • Инициируется сообщение UDP, содержащее такой фрагмент, его порядковый номер (более одного раза) в потоке и контрольную сумму или хэш.
  • Массив состояния помечает этот фрагмент как «отправленный/ожидающий» с отметкой времени.
  • Отправка останавливается, если используется весь массив состояния (окно отправки)

На принимающей стороне:

  • полученные пакеты проверяются по контрольной сумме,
  • поврежденные пакеты признаются отрицательно, если все копии порядкового номера совпадают, в противном случае отбрасываются
  • Пакеты OK помечаются в массиве состояния как «полученные/ожидающие» с отметкой времени.
  • Подтверждение работает путем отправки пакета подтверждения, если либо получено достаточно фрагментов для заполнения пакета подтверждения, либо временная метка самого старого «получения / ожидания» становится слишком старой (от нескольких мс до 100 мс).
  • Пакеты подтверждения нуждаются в контрольной сумме, но не в последовательности.
  • Чанки, для которых было отправлено подтверждение, помечаются как «подтвержденные/ожидающие» с отметкой времени в массиве состояния.

На стороне отправки:

  • Пакеты подтверждения принимаются и проверяются, поврежденные пакеты отбрасываются
  • Чанки, для которых было получено подтверждение, помечаются как «подтверждено/готово» в массиве статусов.
  • Если первый блок в массиве состояния помечен как «подтверждено/готово», массив состояния перемещается вверх до тех пор, пока его первый блок снова не станет выполненным.
  • Это может освободить один или несколько неотправленных фрагментов для отправки.
  • для фрагментов со статусом «отправлено/ожидание» тайм-аут временной метки запускает новую отправку для этого фрагмента, поскольку исходный фрагмент мог быть потерян.

На принимающей стороне:

  • Прием фрагмента i+N (где N — ширина окна) помечает фрагмент i как подтвержденный/готовый, перемещая окно приема вверх. Если не все фрагменты, выскальзывающие из окна приема, отмечены как «подтвержденные/ожидающие», это представляет собой неисправимую ошибку.
  • для фрагментов со статусом «подтверждено/ожидание» тайм-аут временной метки запускает новое подтверждение для этого фрагмента, поскольку исходное сообщение подтверждения могло быть утеряно.

Очевидно, что есть необходимость в специальном типе сообщения от отправляющей стороны, если окно отправки выдвигается за конец файла, чтобы сигнализировать о приеме подтверждения без отправки куска N+i, мы реализовали это, просто отправив N кусков больше, чем существуют, но без полезной нагрузки.

person Eugen Rieck    schedule 02.04.2013
comment
Это именно то, что я сказал: ... сделать его менее чем оптимальным протоколом для прямой передачи файлов и это, скорее всего, приведет к повторной реализации TCP. Мои рекомендации по внедрению начинаются со слов Если вы хотите или должны использовать UDP, так что я полностью с вами. 1. Вы должны использовать TCP, 2. только если вы должны использовать UDP, то ... - person Eugen Rieck; 03.04.2013
comment
Спасибо за исчерпывающий ответ. Является ли этот подход тем, который называется «обратный запрос N ARQ»? - person uylmz; 10.04.2013

Вы можете быть уверены, что пакеты, которые вы получаете, такие же, как и отправленные (т. е. если вы отправляете пакет A и получаете пакет A, вы можете быть уверены, что они идентичны). CRC транспортного уровня, проверяющий пакеты, обеспечивает это. Однако, поскольку UDP не имеет гарантированной доставки, вы должны быть уверены, что получили все, что было отправлено, и вам нужно убедиться, что вы правильно заказываете это.

Другими словами, если пакеты A, B и C были отправлены в таком порядке, вы могли бы фактически получить только A и B (или ничего). Вы можете получить их не по порядку, C, B, A. Таким образом, ваша проверка должна позаботиться о аспекте гарантированной доставки, который обеспечивает TCP (проверить порядок, убедиться, что все данные есть, и уведомить сервер о повторной отправке того, что вы сделали). t получать) в той степени, в которой вы нуждаетесь.

Причина предпочтения UDP перед TCP заключается в том, что для некоторых приложений не имеет значения ни порядок данных, ни их полнота. Например, при потоковой передаче аудиопакетов AAC отдельные аудиокадры настолько малы, что небольшое их количество можно безопасно отбросить или воспроизвести не по порядку, не нарушая впечатления от прослушивания в какой-либо значительной степени. Если 99,9% пакетов получены и упорядочены правильно, вы можете нормально воспроизводить поток, и никто этого не заметит. Это хорошо работает для некоторых сотовых/мобильных приложений, и вам даже не нужно беспокоиться о повторной отправке пропущенных кадров (обратите внимание, что Shoutcast и некоторые другие серверы в некоторых случаях используют TCP для потоковой передачи [для облегчения внутриполосных метаданных], но они не не должен).

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

person par    schedule 02.04.2013
comment
Нет проблем, я рад, что смог помочь. Спасибо за щедрость! - person par; 04.04.2013
comment
Я думаю, что этот ответ представляет собой просто общую информацию о TCP и UDP (которую можно найти в каждой сетевой книге или в Интернете), а не точный ответ на мой вопрос. Я спросил, обеспечивает ли UDP проверку ошибок данных или нет. - person uylmz; 07.04.2013
comment
Что вы имеете в виду под данными? Мой ответ поясняет, что протокол UDP обеспечивает проверку целостности для каждого пакета, но это все. Проверка целостности полезной нагрузки, что означает, что совокупные данные более чем одного пакета не предоставляются UDP. Целостность совокупных данных включает в себя правильную последовательность полученных пакетов и обеспечение того, чтобы все они были доставлены для данной полезной нагрузки. TCP делает это, UDP - нет. - person par; 08.04.2013
comment
Кстати, в вашем вопросе говорится, что вам была поставлена ​​классическая задача передачи файлов по UDP. UDP не подходит для передачи файлов. Для этого вы должны использовать TCP, иначе вы просто будете пытаться переопределить TCP. - person par; 08.04.2013
comment
По фразе классическая задача передачи файлов по UDP. Я имел в виду, что это очень распространенный школьный проект для студентов CS. Цель состоит в том, чтобы заново изобрести колесо TCP, может быть немного больше. - person uylmz; 10.04.2013

Протокол UDP использует ту же стратегию проверки пакетов с ошибками, что и протокол TCP — 16-битную контрольную сумму в заголовке пакета.

Структура пакета UDP хорошо известна (так же, как и TCP), поэтому пакет можно легко подделать, если он не зашифрован, добавление еще одной контрольной суммы (например, CRC-32) также сделает его более надежным. Если цель состоит в том, чтобы зашифровать данные (вручную или по каналу SSL), я бы не стал добавлять еще одну контрольную сумму.

Учтите также, что пакет может быть отправлен дважды. Убедитесь, что вы относитесь к этому соответствующим образом.

Вы можете проверить структуру обоих пакетов в Википедии, у обоих есть контрольные суммы:

Вы можете более подробно изучить структуру пакета TCP, чтобы получить советы о том, как поступать с отброшенными пакетами. Протокол TCP использует для этой цели «порядковый номер» и «номер подтверждения».

Я надеюсь, что это поможет, и удачи.

person DarkCompiled    schedule 02.04.2013

UDP будет отбрасывать пакеты, которые не соответствуют внутренней контрольной сумме для каждого пакета; Проверка CRC полезна для определения на прикладном уровне, если полезная нагрузка кажется завершенной, то, что было получено, действительно завершено (нет отброшенных пакетов) и соответствует тому, что было отправлено (без посредников или других атак). .

person Adrian    schedule 02.04.2013
comment
Чтобы уточнить, проверка CRC на прикладном уровне должна выполняться для полезной нагрузки, чтобы убедиться, что все данные есть и правильно упорядочены, а не для отдельных пакетов. Вам не нужно дублировать то, что делает транспортный уровень. - person par; 02.04.2013