Как установить время ожидания повторной сборки UDP-пакетов в Windows 10

В настоящее время я разрабатываю приложение для получения изображений в Visual C++, которое получает данные изображения с аппаратного устройства UDP с ограниченными возможностями (т.е. без контрольной суммы UDP). Устройство имеет гигабитное соединение с выделенным коммутатором, а ПК использует выделенную сетевую карту и 10-гигабитное соединение с этим коммутатором.

Передаваемые данные изображения состоят из пакетов размером от 6528 до 19680 байт. Эти пакеты фрагментируются аппаратным устройством и реконструируются сетевым стеком на ПК.

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

Мы не можем вычислить контрольную сумму UDP на аппаратном устройстве из-за его ограниченных возможностей.

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

Нам придется реализовать собственный протокол поверх UDP и «вручную» фрагментировать и реконструировать данные, но мы могли бы избежать этого, если бы нашли способ уменьшить время ожидания реконструкции пакетов в Windows до 500 мс или меньше.

Я искал информацию в Google и Stackoverflow, но результатов не так много, и ни один из них не помог.

Отсюда вопрос: есть ли способ уменьшить время ожидания реконструкции для фрагментов IPv4 UDP в Windows 10 с помощью реестра, API Windows или любой другой магии, или у вас есть лучшее предложение?


person Andreas H.    schedule 19.04.2018    source источник
comment
сообщение UDP создается из фрагментов в пределах тайм-аута приема, настроенного для сокета (т. е. если полное сообщение не приходит, вы получаете ошибку тайм-аута). Вы можете настроить этот тайм-аут на любое желаемое значение.   -  person C. Gonzalez    schedule 20.04.2018
comment
Я попробовал это с тайм-аутом 500 мс, но я все еще получаю пакеты, созданные из фрагментов 20-секундной давности. Я считаю, что по крайней мере в Windows RCVTIMEO настраивает только максимальное время блокировки вызовов recvfrom().   -  person Andreas H.    schedule 21.04.2018
comment
Пожалуйста, взгляните на blogs.technet.microsoft.com/nettracer/2010/06/03/   -  person Andreas H.    schedule 23.04.2018


Ответы (1)


Поскольку Windows 2000 жестко закодирована, нет официального способа изменить тайм-аут повторной сборки ip-пакетов из-за строгой совместимости с RFC 2460.

Подробности можно прочитать здесь: https://blogs.technet.microsoft.com/nettracer/2010/06/03/why-doesnt-ipreassemblytimeout-registry-key-take-effect-on-windows-2000-or-later-systems/

В настоящее время кажется, что единственной возможностью является использование сырых сокетов, которые ограничены начиная с Windows 7 и доступны не у каждого поставщика сокетов. Это значительно усложнило бы приложение.

Мы изменим наш программный протокол, чтобы пакеты размером > 1400 байт вообще не отправлялись. Это заставляет нас заботиться о фрагментации в нашем программном обеспечении, но предотвращает фрагментацию IP-пакетов и все ее ловушки. Возможно, это правильный способ справиться с такими проблемами.

person Andreas H.    schedule 23.04.2018
comment
Меня по-прежнему интересует эта тема. Пожалуйста, докажите, что я ошибаюсь, если у вас есть другая информация! - person Andreas H.; 23.04.2018