?

Log in

 
 
27 January 2007 @ 04:52 pm
Общая концепция фильтров  

В общем случае фильтр – это довольно простая штука, которая получает откуда-то данные, обрабатывает их, и куда-то, затем, обработанные данные отправляет. Любой обработчик сетевого соединения является фильтром. Сразу же можно выделить три концептуальные части любого фильтра. Это приемная часть, которая занимается получением данных откуда-то, собственно обработчик, и передающая часть. Подобные абстракции предоставляют многие сетевые библиотеки, которые реализуют алгоритмы взаимодействия с сетью, оставляя программисту только реализацию обработки данных.

Однако программисту, помимо реализации алгоритма обработки, приходиться заниматься и другими малоприятными вещами, такими как сериализация/десериализация данных и обеспечения целостности приема-передачи.

Чтобы передать куда-либо данные их часто бывает необходимо перевести в последовательную форму (сериализовать). В случае с простыми структурами данных эта процедура может оказаться достаточно простой, достаточно знать расположение этой структуры в памяти и ее размер. Однако если мы передаем эту структуру по сети на компьютер с другой архитектурой, может возникнуть масса проблем, такие как другой порядок байтов в слове или количество байт отведенных под какой-либо тип данных. Аналогичная ситуация и с десерелизацией. Классы пространства имен migashko::filters не предоставляют универсальные алгоритмы сериализация/десериализация, однако с помощью удобных абстракций вы можете один раз реализовать эти механизмы и повторно использовать.

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

Обратная ситуация при передаче данных в сеть. Если мы используем блокируемый ввод/вывод, то проблем особых нет – операция записи блокируется до тех пор, пока все данные не будут отправлены. Проблема в том, что на операции записи поток выполнения программы блокируется, что не всегда хорошо. При неблокируемом вводе/выводе эта проблема не встает, но появляется другая. Не все данные могут быть переданы за одну операцию, поэтому оставшиеся данные необходимо будет передать в следующий раз. В общем, обеспечение целостности приема и передачи не является непосильной задачей, но неприятной и неинтересной это точно. Классы пространства имен migashko::filters имеет в своем составе эффективные реализации алгоритмов приема/передачи данных по неблокируемым сокетам (дескрипторам).

Таким образом, в фильтре можно выделить следующие составные части:

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

Пользователю чаще всего придется реализовывать класс handler, реже read_filter_handler, write_filter_handler, в которых реализуются алгоритмы сериализации/десериализации данных и анализа входного потока, остальные классы также заменяемы по необходимости. Я, например, посчитал ненужным алгоритму передачи данных (класс sender) использовать парсер (как на reciver), однако вы можете считать иначе, просто замените стандартную реализацию sender на свою.

 
 
Current Location: Дома