Skip to content

About

Визуализация топологий программно-конфигурируемых сетей и расчет QoS-маршрутов (MCP/MCOP/CSP/LARAC, нечеткая логика). PyQt5

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

SDN Visualizer

Настольное приложение на PyQt5 для проектирования топологий программно-конфигурируемых сетей (ПКС) и расчёта на них маршрутов с ограничениями по качеству обслуживания.

Курсовая работа, версия 1.4.

Автор: Жаднов Александр


Скриншот

Главное окно SDN Visualizer

Топология из 22 коммутаторов с контроллером c0. У каждой связи подписана задержка; красным выделен найденный маршрут, справа — плавающие панели свойств двух связей и одного коммутатора. Вертикальный тулбар слева переключает режимы работы.


Что это делает

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

холст  ──▶  метрики связей  ──▶  матрицы смежности  ──▶  алгоритм маршрутизации
                                                              │
                              результат  ◀──  подсветка путей + таблица QoS
                              экспорт   ──▶  *.sdn.xml  |  *.sdn.py (Mininet)  |  *.txt

Функциональность

Рисование и редактирование

  • 5 режимов работы: выделение, добавление хоста / коммутатора / контроллера, проведение связи. Режим переключается вертикальным тулбаром слева.
  • Связи подписываются метриками; переключение по кругу задержка → полоса → потери → все (кнопка в тулбаре).
  • Свойства устройства (ID, тип, IP, MAC, порт) и связи (полоса, задержка, потери) редактируются в док-панелях, а не только в плавающих окнах.
  • IP/MAC/порт проставляются автоматически: хостам 10.0.0.N, контроллерам 127.0.0.N, порт 6653 + N - 1.
  • Плавающие окна без рамки, поверх всех, с перетаскиванием.

Алгоритмы маршрутизации

Четыре классических многокритериальных

Построены на Yen's k-shortest paths и собственном Дейкстре. Метрики: задержка (мс), потери (%), полоса (Мбит/с). Реализация — ui/algorithms.py.

Алгоритм Формулировка Возвращает
MCP Multi-Constrained Path — все k кандидатов, удовлетворяющих порогу по метрике 1, плюс все, удовлетворяющие порогу по метрике 2 список допустимых маршрутов
MCOP Multi-Constrained Optimal Path — лексикографически: минимум по метрике 1, при равенстве — минимум по метрике 2 один оптимальный
CSP Constrained Shortest Path — k кандидатов по оптимизируемой метрике, фильтр по ограничивающей, затем минимум один маршрут
LARAC Lagrangian Relaxation — агрегированная метрика m₁ + λ·m₂, порог r₁ + λ·r₂, k кандидатов по агрегату список

Диалог настройки (QoSDialog) позволяет выбрать любую пару «оптимизируемая / ограничивающая» метрику, k от 1 до 20, оба порога и λ ∈ [0, 10]. Настройки сохраняются в QSettings. Видимые поля переключаются в зависимости от выбранного алгоритма.

Полоса перед передачей в алгоритм инвертируется в 1/bw — иначе «больше лучше» превратилось бы в «меньше лучше» для минимизации.

Пятый — нечёткая логика

ui/fuzzy_qos.py. Классические алгоритмы выше требуют от аналитика заранее задать числовые пороги и веса. Здесь вместо этого каждое ребро оценивается нечётким числом качества, и уже эти оценки становятся весами для маршрутизации.

Классический нечёткий вывод Мамдани в три этапа.

1. Фаззификация — треугольные функции принадлежности, три терма на метрику (низкая / средняя / высокая):

def fuzzify_delay(self, delay):
    low    = max(0, min(1, (50 - delay) / 30)) if delay <= 50 else 0
    medium = max(0, min(1, (delay - 20) / 30, (80 - delay) / 30)) if 20 <= delay <= 80 else 0
    high   = max(0, min(1, (delay - 50) / 30)) if delay >= 50 else 0

Пороги подобраны так, чтобы шкалы задержки (мс), потерь (%) и полосы (Мбит/с) давали сопоставимые по смыслу термы.

2. Правила — четыре нечёткие импликации, агрегация min по предпосылкам и max по заключениям:

Правило Предпосылка → Заключение
1 задержка низкая И потери низкие И полоса высокая → excellent
2 задержка низкая И (потери средние ИЛИ полоса средние) → good
3 задержка средняя И потери средние → average
4 задержка высокая ИЛИ потери высокие → poor
rules_output['excellent'] = min(delay['low'], loss['low'], bandwidth['high'])
rules_output['good']      = min(delay['low'], max(loss['medium'], bandwidth['medium']))
rules_output['poor']      = max(delay['high'], loss['high'])

3. Дефаззификация — взвешенное среднее по центрам термов (0.9 / 0.7 / 0.5 / 0.2):

numerator   = 0.9*excellent + 0.7*good + 0.5*average + 0.2*poor
denominator = sum(rules_output.values())
return numerator / denominator if denominator > 0 else 0

Результат — число в [0, 1].

Маршрутизация по нечётким оценкам. Итоговая оценка ребра — средневзвешенная качество по трём метрикам; вес ребра для маршрутизации — 1 - quality, то есть чем лучше связь, тем дешевле. Дальше по этой матрице работает тот же yen:

quality = self.calculate_link_quality(delay_matrix[i][j],
                                       loss_matrix[i][j],
                                       bandwidth_matrix[i][j])
fuzzy_weights[i][j] = 1.0 - quality
...
routes = yen(fuzzy_weights, src, dst, k)

То есть аналитику достаточно выбрать «fuzzy logic» вместо ручных порогов — и Yen's остаётся тем же алгоритмом, меняется только функция стоимости ребра.

Отдельный диалог Fuzzy QoS Routing Results показывает для каждого найденного маршрута суммарную задержку, потери, минимальную полосу по пути и итоговую нечёткую оценку качества.


Сегментация графа

ui/algorithms1.py — четыре алгоритма разбиения сети на сегменты:

Алгоритм Метод
Girvan_Newman_Segmentation итеративное удаление ребра с максимальной betweenness (алгоритм Брандеса), затем выделение компонент связности
binarySegmentation BFS-разметка прыжками от источника, затем повторное деление пополам
greedySegmentation BFS-разметка, деление узлов на n примерно равных групп
connectivitySegmentation минимальное остовное дерево (Прим, кучей), группировка листьев с родителями, слияние сегментов при Q = внутренние / (внешние + ε) < 0.3

Формат топологии

Читается и пишется собственный XML (utils/file_io.py), парсер — стандартный xml.etree.ElementTree, без внешних библиотек.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE topology>
<Network>
  <Hosts>        <Host x="100" y="80" ip="10.0.0.2" mac="00:00:00:00:00:02"/>
  </Hosts>
  <Switches>     <Switch x="508" y="458"/>
  </Switches>
  <Controllers>  <Controller x="461" y="194" ip="127.0.0.1" port="6653"/>
  </Controllers>

  <SSLinks>      <Link node1="s2" node2="s1" bandwidth="1" delay="22" loss="0"/>
  </SSLinks>
  <CSLinks>      <Link node1="c0" node2="s1"/>
  </CSLinks>

  <Texts/>
</Network>

SSLinks — связи коммутатор↔хост/коммутатор, несут метрики. CSLinks — контроллер↔коммутатор, метрики игнорируются и при импорте заменяются на 1.0 / 1.0 / 0.0.

Узлы в связях адресуются ролевыми именами h1…hN, s1…sN, c0…cN-1; первый символ выбирает секцию, число — 1-based индекс (для контроллеров 0-based) в порядке документа. При импорте настоящие идентификаторы (host1, switch1, controller1) генерируются заново по порядку документа, при экспорте устройства перегруппировываются по типу и нумеруются обратно в ролевые имена. Схемы и XSD нет — парсер снисходителен, отсутствующее поле молча берёт значение по умолчанию.

Главная хрупкость схемы — привязка к порядку документа. Вставка хоста в середину <Hosts> сдвигает нумерацию всех, кто после него.


Экспорт

Формат Назначение
*.sdn.xml собственный формат топологии topology.sdn12.xml, round-trip
*.sdn.py готовый скрипт Mininet: OVSKernelSwitch, TCLink с bw/delay/loss, RemoteController на 127.0.0.1:6653
*.txt метрики в формате n1-n2:задержка,полоса,потери — вход для внешних алгоритмов

Структура

main.py                     точка входа, настройка логирования, обработчик исключений
core/
  app.py                    SDNVisualizerApp — QApplication + QGraphicsView
  models.py                 DeviceType, @dataclass Device и Link
  scene.py                  NetworkScene + элементы графа (самая большая часть)
ui/
  main_window.py            главное окно, меню, док-панели, пайплайн QoS
  algorithms.py             dijkstra, recover, yen, MCP, MCOP, CSP, LARAC
  fuzzy_qos.py              нечёткий вывод Мамдани + маршрутизация по fuzzy-весам
  algorithms1.py            4 алгоритма сегментации графа
  algorithms2.py            копия algorithms.py
  device_panel.py           свойства устройства
  link_panel.py             свойства связи
  toolbar.py                вертикальный тулбар, режимы, горячие клавиши
  theme.py                  палитра и генерация Qt StyleSheet
  segmentation_dialog.py    диалог выбора алгоритма сегментации
  floating_windows.py       окна без рамки, QoSDialog, QoSResultsDialog
utils/file_io.py            импорт/экспорт XML, генератор Mininet, экспорт метрик
others/                     тестовые топологии + парсер метрик + пример Mininet-скрипта
icons/                      SVG-иконки

NetworkScene — самая большая часть. Классы: SvgDeviceItem (SVG-иконка + жирная подпись короткого ID), NetworkLinkItem (с метрикой-плашкой, подсветкой QoS, отрисовкой рамки выделения), NetworkDeviceItem (устаревший цветной круг, фактически мёртвый), плюс два notifier-класса на QObject для оповещений об изменении позиции и свойств.

Связи перерисовываются в реальном времени при перетаскивании узла: сигнал positionChanged → update_position(). Во время проведения связи рисуется живая пунктирная резиновая линия. Выделение рамкой, Qt-эффекты выделения, z-порядок (узлы 10, связи 5, подсветка 10).


Запуск

Зависимость ровно одна: PyQt5 (+ PyQt5_svg для рендера иконок). Всё остальное — стандартная библиотека. networkx и matplotlib в коде не используются: матрицы смежности — обычные вложенные списки. Нечёткая логика реализована вручную, numpy в fuzzy_qos.py импортируется, но не используется.

pip install PyQt5==5.15.11 PyQt5_svg
python main.py

Python 3.12. Запускать из корня sdn_visualizer/: пакетных __init__.py нет, импорты абсолютные (from core.app import ...).


Известные дефекты

Приложение в рабочем состоянии, но код не чистился. Что есть:

  • ui/algorithms1.py — файл продублирован дословно: строки 1–311 повторены как 313–623, включая импорты. Вторые определения затирают первые. Модуль при этом не импортируется ниоткуда — сегментация в приложении сейчас недоступна.
  • ui/algorithms2.py — побайтовая копия ui/algorithms.py (разница в 1 байт). Тоже не используется.
  • SegmentationDialog импортируется в main_window.py, но ни разу не создаётся. Кнопка в тулбаре подписана «Run Segmentation Algorithm», хотя вызывает пайплайн маршрутизации. Подпись осталась от прежней версии.
  • В FuzzyQoS.__init__ параметры delay_weight, loss_weight, bandwidth_weight и quality_threshold сохраняются в поля, но нигде не используются — правила в fuzzy_rules захардкожены. То есть настроить веса метрик через диалог нельзя, несмотря на то что поля под это заведены. quality_threshold не фильтрует маршруты, а только хранится.
  • TransparentPanel определён дважды — в device_panel.py и link_panel.py, идентично.
  • closeEvent в main_window.py определён дважды; второй перекрывает первый, поэтому док-панели при выходе не закрываются.
  • scene.py вызывает self.scene().link_double_clicked(...) — такого метода на NetworkScene нет, двойной клик прямо по линии падает с AttributeError. Работает только ветка через двойной клик по подписи.
  • algorithm() пишет others/metric_data.txt внутрь репозитория при каждом запуске расчёта — файл перезаписывается, в git это даст лишний diff. В sdn_visualizer.log (104 КБ) видно, что лог тоже растёт в рабочем каталоге.
  • Типизация практически отсутствует: аннотаций нет нигде, кроме полей dataclass в models.py, трёх функций в theme.py и сигнатуры fuzzy_qos.
  • Тестов нет вообще. Файлы others/test1.xml…test4.xml — ручные фикстуры, а не автотесты.
  • Язык смешанный: докстринги и комментарии на русском, строки UI частично на русском («Свойства устройства», «Сохранить изменения»), частично на английском (File, Open, Algorithm, интерфейс QoSDialog, Fuzzy QoS Routing Results), сообщения лога — на английском.

Про иконки

SVG-иконки в icons/ — сторонняя графика, перекрашенная под палитру приложения. python_export.svg явно производная от логотипа Python. Лицензия и происхождение из репозитория не установлены — атрибуция не указана.


Атрибуция

fig21.sdn.xml и fig22.sdn.xml (13 и 22 коммутатора) названы по рисункам из внешнего источника — скорее всего из методических материалов или статьи. Перед публикацией стоит уточнить происхождение.


Лицензия кода

MIT.

About

Визуализация топологий программно-конфигурируемых сетей и расчет QoS-маршрутов (MCP/MCOP/CSP/LARAC, нечеткая логика). PyQt5

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages