Есть ли «хороший» способ справиться с повторной сборкой многоадресных рассылок из нескольких источников? - PullRequest
0 голосов
/ 06 декабря 2008

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

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

Кажется, это очень распространенный вариант использования. Есть ли что-нибудь, что может помочь мне сделать эту работу без того кода, который у меня есть сейчас? Или существует установленный шаблон C ++ (Boost или иным образом), который может выполнять такую ​​работу?

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

Заранее спасибо за любые мысли по этому вопросу.

Jamie

1 Ответ

2 голосов
/ 07 декабря 2008

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

  • Если вы используете многоадресную UDP-рассылку, вы, вероятно, выполняете какую-то последовательность протоколов в пользовательском пространстве, чтобы иметь дело с потерянными или дублированными пакетами. Независимо от того, какую оптимизацию вы хотите сделать, не поддавайтесь искушению , чтобы нарушить разделение между вашим приложением и уровнем протокола.
  • std::vector, для большинства целей, идентично необработанному динамически распределенному символьному буферу. Не стесняйтесь использовать его только потому, что это слой абстракции. Однако в двух случаях вам следует избегать этого:
    • Если вы можете избежать использования статически распределенных буферов
    • Если вам нужно передать владение буфером в нисходящем направлении (хотя, если вы проектируете осторожно, swap() может быть достаточно)
  • Предварительное распределение - ваш друг. Если у вас может быть набор буферов, доступных для использования при поступлении данных, вы можете удалить большинство динамических распределений из быстрого пути выполнения.
  • Минимизировать копии памяти. Если вы можете обрабатывать данные в одном стеке вызовов, у вас есть шанс избежать копий. Если вам нужно передать данные в другой поток, возможно, вам придется скопировать данные.
  • Если ваше приложение может обрабатывать фрагментированные буферы (а не объединять все данные в один буфер), посмотрите writev и readv.

Я не верю, что любое консервированное решение решит ваши проблемы. Boost ASIO, libevent и т. Д. Будут обрабатывать абстракции сокетов для вас, но то, что вы делаете со своими данными, остается вашей обязанностью после их доставки.

...