Вопросы по UDP в C # и пути UDP от сетевого интерфейса к моему приложению - PullRequest
1 голос
/ 05 июля 2011

Я написал приложение на C #, которое получает UDP-пакеты, непрерывно передаваемые с электронного устройства.

Электронное устройство подключено напрямую к ПК, на котором запущено приложение, и к нему не подключены коммутаторы или другие сетевые устройства.

Я представляю, что сетевая инфраструктура ПК выглядит следующим образом:

  1. Сетевой интерфейс (сетевая карта) принимает данные и обрабатывает их до транспортного уровня, помещает пакеты в буфер и отправляет прерывание в ОС.
  2. ОС обрабатывает прерывание в какой-то момент и очищает буфер сетевого интерфейса (т. Е. Все пакеты в буфере очищаются).
  3. ОС сообщает платформе .NET, что данные доступны.
  4. Моя программа собирает пакеты и обрабатывает их.

Теперь, когда я использую UDP, я ожидаю увидеть потерю пакетов и дубликаты и т. Д., И я это вижу. Кажется, что выпадение происходит, когда ПК делает что-то еще (я удаленно управляю ПК с помощью удаленного рабочего стола через второй сетевой интерфейс на ПК).

Могу ли я быть уверен, что если ОС получила пакеты, они будут переданы моему приложению? (Интуитивно я думаю; да, потому что ОС будет использовать оперативную память в качестве буфера, поэтому там будет много места.)

Если это так, я подозреваю, что ОС захватывает все пакеты с сетевого интерфейса, которые могли собраться с тех пор, как сетевой интерфейс вызвал прерывание, и помещает их в ОЗУ. Если это так, то выполняет ли .NET каждый из этих пакетов, вызывая обратные вызовы в .NET и мою программу, связанную с полученным пакетом?

Интуитивно я бы также обвинил сетевой интерфейс в потере пакетов из-за переполнения буфера до того, как ОС сможет его очистить. Это правильно?

Я также подозреваю, что анализаторы пакетов также получают данные ПОСЛЕ того, как ОС их получила, и поэтому данные, полученные анализатором пакетов, и данные, полученные моей программой, должны быть идентичны.

Я написал тестовую программу, которая передает данные UDP 1 КБ на мой собственный сетевой интерфейс с частотой 1000 Гц. Программа также получает данные и проверяет, были ли данные получены по порядку. (Пакеты содержат номер пакета). Я могу заключить, что они получены не по порядку, и что больше принимаются не по порядку, когда компьютер делает что-то еще. (Я не ожидал такого поведения, поэтому я не написал подпрограмму для проверки потерянных пакетов. Я сделаю это завтра.)

Для завершения. Как я могу уменьшить потерю пакетов? Это хорошая идея, чтобы создать буфер в C #, или я могу полагаться на ОС, чтобы иметь буфер? Можно ли настроить размер буфера ОС? Можно ли установить размер буфера сетевого интерфейса?

Спасибо.

1 Ответ

0 голосов
/ 27 августа 2011

Множество вопросов, позвольте мне ответить, что я могу (без определенного порядка)

Чем больше пакет, тем выше вероятность фрагментации, тем больше количество фрагментов. Теоретически, если вы потеряете фрагмент, вы потеряли пакет (нижележащие слои не могут повторно собрать пакет, и поэтому он отброшен)

Ряд источников предлагают, чтобы UDP-пакеты имели размер около 576 байт (см. http://www.faqs.org/rfcs/rfc791.html), чтобы гарантировать, что фрагментация никогда не произойдет.

В ОС имеется довольно большой буфер (по умолчанию 4M, если память у меня правильная), но он находится на уровне ядра и не так легко просматривается. Тем не менее, вы можете настроить ReceiveBufferSize в классе Socket, чтобы расширить это значение. Если вы работаете на 32-битной машине, я бы сохранил это значение не выше 8M, для 64-битной вы можете пойти немного выше, я думаю, что для нашего приложения мы достигли 64M.

UDP не дает вам никакого порядка пакетов, если вам нужны упорядоченные пакеты, вы немедленно возвращаетесь в TCP-land (или пишете приложения UDP, которые в основном реализуют TCP / IP, что приводит к потере значения UDP)

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

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

...