Сетевое приложение в архитектуре "клиент-сервер" на базе синтаксического анализатора xml-файлов

Разработка сетевого приложения в архитектуре клиент-сервер на базе синтаксического анализатора xml-файлов, позволяющего в реальном времени проводить моделирование сетей Петри. Оригинальные компоненты интерфейса, структуры передачи данных и их отображения.

Рубрика Программирование, компьютеры и кибернетика
Вид диссертация
Язык русский
Дата добавления 21.02.2019
Размер файла 2,8 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ

Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования

Пензенский государственный университет

Политехнический институт

ДИССЕРТАЦИЯ

на соискание степени магистра техники и технологии на тему

Сетевое приложение в архитектуре "клиент-сервер" на базе синтаксического анализатора xml-файлов

по направлению 09.04.01 «Информатика и вычислительная техника»

Автор работы Захватов Никита Алексеевич

Руководитель Зинкин С.А.

Нормоконтролёр Кучин А.В.

Заведующий кафедрой Пащенко Д.В.

Пенза, 2018

Реферат

сетевой архитектура петри интерфейс

Пояснительная записка содержит 85 страниц, 42 рисунков, 5 литературный источник, 2 приложения.

КОМПЬЮТЕРНЫЕСЕТИ,ПЕРЕДАЧА ДАННЫХ, СЕТЕВЫЕ ТЕХНОЛОГИИ, АРХИТЕКТУРА КЛИЕНТ-СЕРВЕР, СЕТЕВОЕ ПРОГРАММИРОВАНИЕ, СЕТЕВЫЕ ПРИЛОЖЕНИЯ, СЕТЬ ПЕТРИ, XML.

Цель работы -- разработка сетевого приложения в архитектуре «клиент-сервер» на базе синтаксического анализатора xml-файлов, позволяющего в реальном времени проводить моделирование сетей Петри по условиям, заданными пользователем или программой созданий сетей Петри.

Содержится описание и применение сетевой технологии, охватывающей спектр вопросов по темам «Сетевые клиент-серверные технологии» для разработки сетевых клиент-серверных приложений»

Объектами исследования являются оригинальные компоненты интерфейса, структуры передачи данных и их отображения.

В результате проделанной работы было разработано сетевое приложение в архитектуре «клиент-сервер» на базе синтаксического анализатора xml-файлов, который позволяет моделировать сети Петри в реальном времени по условиям, заданными пользователем или программой создания сетей Петри. А также быть использовано в учебном процессе студентами, обучающимися в специалитете, бакалавриате и магистратуре по направлениям, связанным с информатикой, вычислительной техникой и обработкой данных.

Содержание

Реферат

Введение

1. Постановка задачи

2. Анализ предметной области

2.1 Выбор и обоснование программного обеспечения (ПО)

3. Изучение и установка ПО для подготовки к созданию приложения

3.1 Установка Qt 5

3.2 Изучение PIPE 5

3.2.1 Работа с файлами

3.2.1.1 Создание новой сети Петри

3.2.1.2 Открыть уже существующий файл

3.2.1.3 Сохранить существующую сеть Петри

3.2.1.4 Закрыть текущую вкладку

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

3.2.2.1 Добавление метки перехода

3.2.2.2 Добавление и изменение позиции

3.2.2.3 Добавление и изменение переходов

3.2.2.4 Добавление и редактирование дуг

3.2.2.5 Редактор параметров задержки переходов

3.2.3 Функциональные задержки переходов

3.2.3.1 Примеры

3.2.4 Анимация сетей Петри

3.2.4.1 Режим анимации

3.2.4.2 Активация перехода

3.2.4.3 Переход назад / вперед

3.2.5 Анализ сетей Петри

3.2.6 Модули анализа

4. Разработка интерфейсов

4.1 Создание сети Петри в PIPE5

4.2 Разработка интерфейсов сервера

4.2.1 Разработка интерфейса загрузки xml-файлов без графической обработки

4.2.2 Разработка интерфейса загрузки xml-файлов с графической обработкой

4.2.3 Разработка интерфейса дополнительных условий

4.3 Разработка интерфейсов клиента

Заключение

Список использованных источников

Приложения

Введение

Компьютерные технологии стали неотъемлемой частью человеческой жизни. При этом интенсивность их использования постоянно растет. Согласно исследованиям, зарубежных ученых, количество людей, работающие с компьютерными технологиями, увеличиваются почти вдвое каждые 5 лет, одновременно с этим многие люди не могут оптимально распределить свое личное время, из-за этого многие не успевают сделать важные дела и получают стрессы на работе.

В связи с ростом объема работ, особенно ближе к закрытию квартала, все большую актуальность приобретают вопросы оптимального управления временем и повышение эффективности работы.

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

Если в основе работы СППР лежат методы искусственного интеллекта, то говорят об интеллектуальной СППР или ИСППР. Близкие к СППР классы систем -- это экспертные системы и автоматизированные системы управления.

Другими словами, данные системы должны облегчить работу людей.

1. Постановка задачи

Исходя из того, что похожих приложений, для изучения их в плане примера, не были найдены, были поставлены следующие задачи: изучить типовые примеры сетевых приложений «клиент-сервер», их интерфейс и функционал, изучить сетевые модели передачи данных (OSI(ВОС) и TCP/IP). Изучить Pipe5 (Platform Independent Petrinet Editor), ее функции и возможности для конечной реализации проекта. Разработать синтаксический анализатор для xml-файлов, созданных в PIPE5. Разработать функционал для взаимосвязи данных xml-файлов и функционала сервера с клиентами, а также для отображения на графической форме содержимого xml-файлов. В качестве приложения для создания сетей Петри необходимо использовать PIPE5 в качестве средств разработки программа Qt5, операционная система Windows 7 и Windows 10.

2. Анализ предметной области

В данной главе рассматриваются общие теоретические сведения о предметной области, а также выбор программного обеспечения.

2.1 Выбор и обоснование программного обеспечения (ПО)

Для нашей работы было выбрано ПО PIPE5, потому что:

Platform Independent Petrinet Editor (PIPE) - открытое программное обеспечение, предназначенное для работы с сетями Петри. Оно позволяет создавать сети Петри, изменять существующие сети, проводить моделирование работы данной сети и исследовать ее параметры. Данное ПО является кроссплатформенным, что позволяет работать на любой платформе, поддерживающей Java.

Рисунок 1 - Пример PIPE

PIPE поддерживает множество функций для создания и редактирования сетей Петри которые отмечены на рисунке 2 и описаны ниже:

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

· Действия по работе с метками -- PIPE поддерживает работу с цветными сетями Петри, благодаря возможности определения нескольких множеств меток. Эти метки можно установить на позиции используя действия по добавлению и удалению меток.

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

· Редактирование компонентов -- PIPE поддерживает операции вырезания, копирования, вставки, удаления, отмены и повтора, чтобы помочь при построении сети Петри.

· Редактирование файлов -- сети Петри могут быть загружены из PNML и сохранены в формате PNML.

· Возможность масштабирования -- для просмотра больших и малых сетей Петри PIPE поддерживает работу с масштабом. Когда сеть Петри не умещается на экране, так же можно использовать прокрутку окна[1].

Рисунок 2 - Пример сложной сети Петри

А также ПО QT, потому что:

Qt - это кросс-платформенная библиотека C++ классов для создания графических пользовательских интерфейсов (GUI) от фирмы TrollTech. Эта библиотека полностью объектно-ориентированная, что обеспечивает легкое расширение возможностей и создание новых компонентов. Она поддерживает огромнейшее количество платформ, таких как Windows 95/98/NT/2000, Linux, Sun Solaris, HP-UX, Digital Unix, IBM AIX, SGI IRIX и многие другие. С момента первого появления коммерческой версии Qt в 1996 году появилось несколько сотен известных по всему миру приложений. Самой известной разработкой на базе Qt является десктоп менеджер для X Windows называющийся, как уже многие догадались, KDE.

Рисунок 3 - Пример Qt5

Существует две версии библиотеки Qt: бесплатная и платная. Бесплатная версия, называемая Qt Free Edition предназначается только для Unix/X11 и разработки программ с открытым исходным текстом. Для разработки коммерческих программ предназначается версия Qt Professional Edition.

Для библиотеки создания GUI объектно-ориентированный язык является единственно пригодным средством, а стандартная объектная модель C++ обеспечивает эффективную и быструю разработку программ, наращивание неограниченных возможностей и быструю модернизацию. Естественно из-за этого в качестве базового языка для библиотеки выбран C++. Но в дополнение к возможностям самого языка в библиотеке Qt добавлены несколько хороших возможностей:

1. мощный механизм коммуникации между объектами с помощью сигналов и слотов

2. механизм создания свойств объектов, которые не поддерживает компилятор C++

3. поддержку событий и фильтров событий

4. перевод строк для поддержки интернационализации

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

6. иерархические деревья объектов, являющихся своего рода генеалогическими деревьями: "прадедушка - дедушка - папаша - сынок", предназначенное для организации внутреннего взаимодействия в "натуральном" виде

7. "охраняемые" указатели, которые автоматически устанавливаются в NULL при удалении объекта, на который ведет ссылка

Все эти возможности реализованы в виде специальных классов C++. Появление новых современных требований к пользовательским интерфейсам влечет за собой и появление новых нестандартных механизмов, которые сам язык программирования обеспечить, не способен, а лишь после создания специализированных классов [2].

3. Изучение и установка ПО для подготовки к созданию приложения

3.1 Установка Qt 5

Для разработки пользовательского приложения было принято решение использовать язык C++, а реализовываться проект будет ПО под названием Qt.

Рисунок 4

Первым делом заполняется информация в полях ввода, в которые нужно вписать свою электронную почту с паролем (рис 5)

Рисунок 5 - Заполнение информации

Вторым шагом выбирается путь установки продукта (рис 6)

Рисунок 6 - Выбор пути

Третьим шагом выбираются, какие версии продукта должны быть установлены (рис 7)

Рисунок 7 - Выбор версий

И последним шагом, когда все пред установочные моменты завершились, начинается установка (рис 8)

Рисунок 8 - Установка

После завершения установки продукт полностью установлен и готов к работе (рис 9)

Рисунок 9 - Рабочая версия

3.2 Изучение PIPE 5

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

Рисунок 10 - Указатель элементов PIPE 5

Обратите внимание, что на Mac все ярлыки с участием Ctrl должны быть заменены нижеперечисленной опцией Cmd.

3.2.1 Работа с файлами

3.2.1.1 Создание новой сети Петри

Создать новую сеть Петри можно, нажав на иконку «», нажав Ctrl-N, или выбрав новую опцию сети Петри в меню «Файл». Появится чистое рабочее пространство, где вы можете создать свою сеть Петри, используя другие действия, описанные ниже. Вашей новой сети Петри будет присвоено уникальное имя по умолчанию, пока вы ее не сохраните. Вы можете перемещаться по всем открытым сетям Петри, щелкнув на желаемом имени сети Петри на панели вкладок над рабочим пространством.

3.2.1.2 Открыть уже существующий файл

Чтобы открыть уже существующую сеть Петри, щелкните на иконку «Открыть» «» или нажмите Ctrl-O. Ваша открытая сеть Петри будет загружена в рабочее пространство, которое является первой вкладкой.

3.2.1.3 Сохранить существующую сеть Петри

Чтобы сохранить существующую сеть Петри, щелкните значок «Сохранить» «», используйте опцию «Сохранить» или нажмите Ctrl-S.

Опция «Сохранить как…» «» также доступна в панели задач, меню или нажатием Ctrl-Shift-S. После сохранения ваша сеть Петри будет переименована на панели вкладок в только что введенное имя для сохранения.

3.2.1.4 Закрыть текущую вкладку

Чтобы закрыть текущую вкладку, нажмите Ctrl-W или щелкните по значку закрытия «».

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

Сеть Петри может быть создана с помощью соответствующих значков на панели задач.

3.2.2.1 Добавление метки перехода

Чтобы добавить метку в сеть Петри, нажмите на иконку «Новая метка» «» или нажмите Ctrl-Shift-T. Появится окно редактора меток, в которое можно добавить новые виды меток, указав им имя и цвет.

Рисунок 11 - Окно редактора меток

Активный вид меток можно изменить с помощью выпадающего меню меток перехода.

Рисунок 12 - Меню выбора вида метки перехода

3.2.2.2 Добавление и изменение позиции

Инструмент создания позиции можно выбрать, щелкнув на иконку «Позиция» «».

Выбрав данный инструмент, щелкните в любом месте рабочего пространства, чтобы создать новую позицию в этом месте. Ей автоматически присвоится имя.

Чтобы изменить атрибуты позиции, такие как имя и объем меток, щелкните правой кнопкой мыши на позиции и нажмите «Изменить позицию». Появится окно редактора позиции, где вы можете ввести новые данные для позиции.

Рисунок 13 - Меню параметров позиции

Активную метку можно добавить или удалить из позиции, выбрав соответствующие значки рядом с активным меню меток«» «». Чтобы изменить, какая метка будет добавлена, выберите метку, которую вы хотите поместить из «меню выбора вида метки перехода», затем нажмите на позицию, чтобы добавить метку.

Метку, возможно, добавить другим способом - используя меню параметров позиции.

3.2.2.3 Добавление и изменение переходов

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

Переход может быть создан где угодно, при нажатии на рабочее пространство. Ему автоматически присваивается имя, как при добавлении места.

Щелкнув правой кнопкой мыши по переходу и нажав в меню пункт «Изменить переход», откроет вам «меню параметров перехода», которое позволит вам редактировать атрибуты переходов и менять тип перехода, выбирая между переходом с задержкой или немедленным переходом.

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

Рисунок 14 - Меню параметров перехода

3.2.2.4 Добавление и редактирование дуг

Нажмите либо на иконку «Обычная дуга» «», либо на значок «Ингибиторная дуга»«», а затем выберите компоненты, между которыми вы хотите создать дугу.

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

При создании дуги, щелкая левой кнопкой мыши внутри рабочего пространства, вы добавите точки пути дуги с прямым изгибом, с зажатой клавишей Shift будут создаваться точки с плавным изгибом.

Нажатие Esc во время создания дуги отменяет её создание.

Рисунок 15 - Пример конфигурации сети Петри в PIPE 5 с описанными выше возможностями

Число меток, требуемых дугой, может быть либо статическим, либо функциональным. Вы можете отредактировать вес дуг, щелкнув правой кнопкой мыши по дуге и выбрав пункт меню «Редактировать вес». Это откроет «меню редактирования веса дуги», где вес может быть установлен для каждого объявленного вида меток.

Рисунок 16 - Меню редактирования веса дуги

3.2.2.5 Редактор параметров задержки переходов

Параметры задержки полезны, поскольку они позволяют создавать общую задержку для временных переходов. Изменение данной задержки приведет к изменению любых переходов, которые используют эту задержку. Нажмите на иконку «Параметры задержки переходов» «» на панели задач и введите имя и значение для данного параметра.

Рисунок 17 - Меню редактора параметров задержки переходов

3.2.3 Функциональные задержки переходов

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

program ::=expression;

expression ::= '(' expression ')' |

expression * expression |

expression / expression |

expression + expression |

'ceil(' expression ')' |

'floor(' expression ')' |

capacity |

token_number |

token_color_number |

INT |

DOUBLE;

capacity ::= 'cap(' ID ')';

token_number ::= '#(' ID ')';

token_color_number ::= '#(' ID ',' ID ')';

Где ID подразумевается имя позиции, или в случае token_color_number имя позиции за которым следует тип метки.

3.2.3.1 Примеры

Примеры функциональных весов с использованием грамматики приведены в таблице ниже.

Таблица 1 - Пример

Выражение

Значение

#(P0)

Сумма всех меток в P0

#(P0, Default)

Число меток группы «По умолчанию»

#(P1, Red)*10

число красных меток, умноженное на 10

floor(10.5/3)

Округление в меньшую сторону 10.5/3, то есть 3

ceil(cap(P5) * 2.5)

округлениевбольшуюсторонувместимости (максимума разрешенных меток)вP5,умноженное на 2.5

#(P0) + #(P2)

сумма чисел всех меток вP1 иP2

3.2.4 Анимация сетей Петри

3.2.4.1 Режим анимации

Вы можете переключать режим анимации для данной сети Петри, нажав кнопку «Режим анимации» «». Этот режим изменяет панель инструментов вверху, чтобы отображать полезные инструменты для анимации. Он также отображает историю анимации в левой части экрана.

3.2.4.2 Активация перехода

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

· Нажать на переход, который вы хотите активировать.

· Нажатие на кнопку «Активация случайного перехода» «».В данном случае, программа выбирает переход, основываясь на приоритетах и типе для активации.

· Нажатие на кнопку «Активация множества перехода». В данном случае, в должны указать, сколько переходов вы хотите активировать, и время задержки между активацией. Затем программа будет выбирать переходы для анимации, основываясь на приоритетах и типе для активации.

Рисунок 18 - Сеть Петри при анимировании

3.2.4.3 Переход назад / вперед

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

3.2.5 Анализ сетей Петри

В PIPE 4, пользователь может провести анализ своей сети Петри, используя любой из доступных модулей, находящихся в левой части графического интерфейса. К сожалению, модули анализа сетей Петри не доступны в PIPE 5, из-за несовместимости. Следующее описание применимо для версии PIPE 4.

3.2.6 Модули анализа

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

· Сравнение - сравнивает две сети Петри и устанавливает, идентичны они или похожи. Модуль предоставляет опции для выбора полей сравнения, таких как идентификаторы компонентов, подсчет количества меток и т. д. Модуль отображает любые различия пользователю на выходе.

· Анализ стохастических сетей Петри (GSPN) - выполняет анализ устойчивого состояния в GSPN, предоставляя информацию о материальных состояниях, распределении в устойчивом состоянии, среднем числе меток на позициях и т. д.

· Инвариантный анализ - вычисляет P-инварианты и T-инварианты, чтобы определить, ограничена ли сеть Петри (ее множество достижимости конечно) и живость.

· Инцидентность и маркировка - вычисляет прямые и обратные матрицы инцидентности сети Петри.

· Редактор запросов производительности - анализирует сеть Петри посредством графического математического языка запросов производительности.

· Граф достижимости/покрытия - создает граф достижимости или покрытия для данной сети Петри.

· Анализ времени реакции - выполняет запросы анализа времени ответа на кластер Camelot в Imperial College London.

· Моделирование - вычисляет среднее количество меток на каждой позиции для заданного количества активаций и повторений.

· Анализ состояний сети - определяет, является ли сеть Петри безопасной, ограниченной и свободной от блокировок.

· Анализ устойчивых состояний - анализирует набор достижимости и рассчитывает устойчивое состояние сети Петри

4. Разработка интерфейсов

4.1 Создание сети Петри в PIPE5

Прежде чем начать разрабатывать интерфейсы под сервер и клиенты, нужно создать пример сети Петри в программе PIPE5, чтобы отталкиваюсь от него создать анализатор и остальные части распознавателя xml-файлов.

Откроем PIPE5 (рис. 19), каждая версия приносит программе, что-то новое, особенно учитывая тот факт, что каждую новую версию выпускают разные корпорации

Рисунок 19 - PIPE5

Добавим 4 события, из которых у нас будет одно начальное событие, а остальные три конечных, сделаем переходы (рис. 20).

Рисунок 20 - События и переходы

Это сделано специально для того, чтобы можно было бы наглядно рассмотреть нашу связь между сервером и клиентами. В нашем случае сервер будет - Р0, а Р1-3 будут у нас клиентами. Добавим связи (рис 21).

Рисунок 21 - Добавление связей

Как видно на рисунке, мы используем самую простую связь, которая никак не пересекается с остальными событиями, чтобы не усложнять наш пример, в дальнейшем анализатор пройдет определенное количество обновлений и корректировок, чтобы можно было обрабатывать сложные связи, которые связаны между собой, как, например, на рисунке 22.

Рисунок 22 - Пример сложной сети Петри

И напоследок, добавим приоритет к одному из событий, который будет играть роль клиента, чтобы во время моделирования работы сети, можно было бы протестировать момент, когда клиенты пришлют на сервер одинаковые результаты, тогда-то нам и понадобится приоритет (рис. 23).

Рисунок 23 - Приоритет

После чего сохраняем и созданный xml-файл кладем в папку к нашему будущему серверу, чтобы было проще найти его в последствии.

4.2 Разработка интерфейсов сервера

Программа, по сути, представляет из себя обычную библиотеку, основные функции которой наследованные от классов. Так, при первоначальной загрузке программы вызывается функция main().

Прототип функции main() приведен в листинге 1.

Листинг 1. Прототип функции main()

#include "myserver.h"

#include <QApplication>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MyServer w(2323);

w.show();

return a.exec();

}

В данном листинге создается объект класса Widget - w; w.show() - загружает виджет при запуске программы; MyServer w(2323) - создает объект сервера с портом 2323.

В функции main() обычно должны выполняться следующие пункты:

· Создание диалогового окна - сервера;

· Загрузка информации из xml-файла;

· Определение количества клиентов для поддержания правильной работы программы

· Создание графической области, в которой будет отображаться информация из xml-файлов.

· Анализация информации для создания диалогового окна с полной информацией об объектах внутри xml-файлов

Рисунок 24 - Сервер

Как видно на рисунке 24, на виджете есть несколько кнопок с разными функциями.

Кнопка «Send» отвечает за отправку сообщений.

Кнопка «XML_SVG» отвечает за загрузку xml-файлов с графическим отображением.

Кнопка «XML» отвечает за загрузку xml-файлов без графики.

Кнопка «Set_C» отвечает за установление дополнительных условий для моделирования работы сетей-Петри.

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

Рисунок 25 - Подключение Клиентов

После с клиентов посылаем сообщения на сервер (рисунок 26). Для того, чтобы убедиться в правильности работы соединения между клиентом и сервером.

Рисунок 26 - Сообщения от клиентов

Прототип функции MyServer() приведен в листинге 2.

Листинг 2. Прототип функции MyServer ()

#include "myserver.h"

#include <QLineEdit>

#include <QCheckBox>

#include <QDomDocument>

#include <QSplitter>

#include <QTableWidget>

MyServer::MyServer(int nPort, QWidget* pwgt /*=0*/) : QWidget(pwgt)

, m_nNextBlockSize(0)

{

m_ptcpServer = new QTcpServer(this);

if (!m_ptcpServer->listen(QHostAddress::Any, nPort)) {

QMessageBox::critical(0,

"Server Error",

"Unable to start the server:"

+ m_ptcpServer->errorString()

);

m_ptcpServer->close();

return;

}

connect(m_ptcpServer, SIGNAL(newConnection()), this, SLOT(slotNewConnection())

);

m_ptxt = new QTextEdit;

lineEdit_4 = new QLineEdit;

m_ptxt->setReadOnly(true);

//Layout setup

QPushButton* wCl = new QPushButton("&Send");

connect(wCl, SIGNAL(clicked()), SLOT(slotWriteClient()));

QPushButton* xmlf = new QPushButton("&XML_SVG");

connect(xmlf, SIGNAL(clicked()), SLOT(xmlLoad()));

QPushButton* xmr = new QPushButton("&XML");

connect(xmr, SIGNAL(clicked()), SLOT(xmlRead()));

QPushButton* setC = new QPushButton("&Set_C");

connect(setC, SIGNAL(clicked()), SLOT(set_Cond()));

QVBoxLayout* pvbxLayout = new QVBoxLayout;

pvbxLayout->addWidget(new QLabel("<H1>Server</H1>"));

pvbxLayout->addWidget(m_ptxt);

pvbxLayout->addWidget(lineEdit_4);

pvbxLayout->addWidget(wCl);

pvbxLayout->addWidget(xmlf);

pvbxLayout->addWidget(xmr);

pvbxLayout->addWidget(setC);

setWindowTitle("Server");

setLayout(pvbxLayout);

}

В данном листинге создается сервер со всеми окнами и кнопками.

m_ptxt = new QTextEdit; - создается объект текстового виджета.

lineEdit_4 = new QLineEdit; - создается объект на текстовую строку.

QPushButton* wCl = new QPushButton("&Send"); - создается объект на кнопку.

connect(wCl, SIGNAL(clicked()), SLOT(slotWriteClient())); - подключает событие на кнопку для перехода к работе функции (slotWriteClient()).

QVBoxLayout* pvbxLayout = new QVBoxLayout; - создается объект макета расположения виджетов.

pvbxLayout->addWidget(m_ptxt); - привязка объектов к макету.

setWindowTitle("Server"); - устанавливаем новое название к главному окошку.

setLayout(pvbxLayout); - устанавливаем наш макет на основное окно приложения.

После загрузки сервера и подключения к нему клиентов нужно загрузить сам xml-файл.

Чтобы загрузить xml-файл, нужно либо нажать на кнопку XML_SVG, либо XML.

4.2.1 Разработка интерфейса загрузки xml-файлов без графической обработки

При нажатии кнопки «XML» появляется окно загрузки файлов рисунок 27.

Рисунок 27 - Окно загрузки

Выбираем файл и нажимаем открыть. Открывается новое окно с результатом анализатора xml-файлов. Результат можно увидеть на рисунке 23.

Рисунок 28 - Результат анализатора

На рисунке 28 мы видим результат работы анализатора. Анализатор разобрал информацию и заполнил таблицу, в которой расписаны все связи между событиями сети-Петри. В столбце «Начало», записывается название начального события. В столбце «Переход», записывается название перехода, который связывает события. В столбце «Конец», записывается конечное название события, с которым связан переход. В столбце «Полный путь», записывается весь путь взаимодействия событий и переходов. В столбце «Приоритет», записывается значение приоритета, если такой имеется. Также анализатор высчитывает, сколько конечных событий мы имеем и блокирует отправку сообщений на клиенты, если они не подходят под количество событий.

Прототип функции xmlRead() приведен в листинге 3.

Листинг 3. Прототип функции xmlRead ()

QString path;

QString filename = QFileDialog::getOpenFileName(this, trUtf8("Open SVG"),path, tr("SVG files (*.svg *.ui)"));;

QDomDocument doc; // объект документа

QFile file(filename); // Открываем наш файл

QString tag1 = "net";

QString tag2 = "place";

QString tag5 = "transition";

QString tag6 = "arc";

QString tag7 = "initialMarking";

QString tag8 = "value";

// Если он не открылся или не удалось передать содержимое в QDocDocument

if (!file.open(QIODevice::ReadOnly) || !doc.setContent(&file))

return;

// Ищем в документе все объекты с тегом g

QDomNodeList gList = doc.elementsByTagName(tag1);

QDomNodeList gPlace = doc.elementsByTagName(tag2);

QDomNodeList gList2 = doc.elementsByTagName(tag5);

QDomNodeList gList3 = doc.elementsByTagName(tag6);

QDomNodeList gList4 = doc.elementsByTagName(tag7);

QDomNodeList gList5 = doc.elementsByTagName(tag8);

// Начинаем их перебирать

qDebug() « tag2 « "нашел = " « gPlace.size();

QString mas1[gList3.length()];

QString mas2[gList3.length()];

QString mas3[gList2.length()];

QString mas4[gPlace.length()];

QString mas6[gList4.length()];

QString mas7[gList4.length()];

Сначала, с помощью QString filename = QFileDialog::getOpenFileName(this, trUtf8("Open SVG"),path, tr("SVG files (*.svg *.ui)"));; - вызываем окно загрузки и выбора xml-файлов, после сохраняем наш файл в переменную filename. После создаем объект документа QDomDocument doc; и открываем наш файл с помощью QFile file(filename); В дальнейшем создаем специальные переменные для поиска тегов с теми же именами в нашем xml-файле QString tag1 = "net"; итд. Впоследствии, создаем списки, в которых начинаем искать наши теги.

Рисунок 29

На рисунке 29 изображена часть кода, отвечающая за нахождение тегов в xml-файле. Для начала выделяем из созданного списка QDomNode gNode = gList.item(i); После чего начинаем искать элемент с тегом, заданный заранее QDomElement rectangle = gNode.firstChildElement(tag2); После идет проверка на не нулевой элемент if (rectangle.isNull()){ qDebug() << tag2 << "не вошел";continue; Если элемент подходит под параметры поиска, то начинается поиск следующего тега в зоне работы выше найденного элемента, с помощью цикла ищем следующий элемент. В последствии таким способом несколько раз будет проведен поиск остальных тегов и получение информации из них.

После закрываем окно и в главном окне пишем «start» (рис. 30).

Рисунок 30 - Начало моделирования

И нажимаем «Send» - отправляем команду клиентам на начало моделирования. После с интервалом в 5 секунд, сервер отправляет сообщение клиентам. И начинает ждать ответа. Результат придет на сервер. Результат будет выведен на экран и по окончанию моделирования, будет выбран лучший вариант, и он также будет выведен на экран, если значение от двух клиентов будет одинаковый, например, равный 2. То будет уже учитываться приоритет. У кого он больше тот вариант и будет выведен на экран. Результат можно увидеть на рисунке 31.

Рисунок 31 - Результат моделирования

Как видно на рисунке 31. На сервер пришло 3 сообщения и после получения последнего сообщения, выведено оптимальное значение. В нашем случае максимальное число.

4.2.2 Разработка интерфейса загрузки xml-файлов с графической обработкой

При нажатии кнопки «XML_SVG» появляется графическое окно рисунок 32.

Рисунок 32 - Графическая область

Появилось окно с пустой областью, нажимаем правую клавишу и нажимаем кнопку «Загрузить» (рисунок 33).

Рисунок 33 - Загрузка

Открывается окно запуска, выбираем нужный файл и нажимаем «Открыть».

Рисунок 34 - Окно загрузки

Результат можно увидеть на рисунке 34.

Рисунок 35 - Результат анализатора

На рисунке 35 мы видим результат работы анализатора. Анализатор разобрал информацию и заполнил таблицу, в которой расписаны все связи между событиями сети-Петри. В столбце «Начало», записывается название начального события. В столбце «Переход», записывается название перехода, который связывает события. В столбце «Конец», записывается конечное название события, с которым связан переход. В столбце «Полный путь», записывается весь путь взаимодействия событий и переходов. В столбце «Приоритет», записывается значение приоритета, если такой имеется. Также анализатор высчитывает, сколько конечных событий мы имеем и блокирует отправку сообщений на клиенты, если они не подходят под количество событий. Также в графической области сгенерировалась сеть-Петри (рисунок 36).

Рисунок 36 - Результат загрузки

Как видно из результата, у нас есть начальное событие (S0), три перехода (T0-2) и 3 окончательных события (S1-3). Так же видно, что у S2 есть приоритет перед другими событиями. Если сравнить результат этой загрузки с результатом анализатора, то увидим, что они одинаковы и программа, значит, работает правильно.

После закрываем окно и в главном окне пишем «start» (рис. 37).

Рисунок 37 - Начало моделирования

И нажимаем «Send» - отправляем команду клиентам на начало моделирования. После с интервалом в 5 секунд, сервер отправляет сообщение клиентам. И начинает ждать ответа. Результат придет на сервер. Результат будет выведен на экран и по окончанию моделирования, будет выбран лучший вариант, и он также будет выведен на экран, если значение от двух клиентов будет одинаковый, например, равный 2. То будет уже учитываться приоритет. У кого он больше тот вариант и будет выведен на экран. Результат можно увидеть на рисунке 38.

Рисунок 38 - Результат моделирования

Как видно на рисунке 38. На сервер пришло 3 сообщения и после получения последнего сообщения, выведено оптимальное значение. В нашем случае максимальное число.

4.2.3 Разработка интерфейса дополнительных условий

После загрузки xml-файлов и перед тем как отправить команду клиентам, можно изменить условия для выбора лучшего решения. По умолчанию у нас стоит нахождения максимального значения, но если перед отправки команды на клиенты, нажать «Set_C», то вызовется интерфейс, который изображен на рисунке 38.

Рисунок 39 - Интерфейс установки условий

Как видим интерфейс состоит из несколько кнопок и чек-боксов. У нас есть несколько вариантов установления условий. Можно поставить больше, либо меньше какого-либо числа. Можно установить поиск максимального, либо минимального числа. Нужно лишь выбрать какой-либо вариант из данных и нажать «Ок», а после посылаем команду клиентам и ждем результат.

Пример:

Выбрали, что результат должен быть больше 5 (рис. 40).

Рисунок 40 - Пример

Нажимаем «ОК», после вводим команду и отправляем клиентам. После ждем результат (рис 41).

Рисунок 41 - Результат примера моделирования сети

Как видим из результата. Клиенты прислал 3 результат и из них был выбран результат, который больше 5. На этом мы закончим рассмотрение и разработка интерфейсов для сервера.

4.3 Разработка интерфейсов клиента

Программа, по сути, представляет из себя обычную библиотеку, основные функции которой наследованные от классов. Так, при первоначальной загрузке программы вызывается функция main().

Прототип функции main() приведен в листинге 4.

Листинг 4. Прототип функции main()

#include "myclient.h"

#include <QApplication>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MyClient w("127.0.0.1", 2323);

w.show();

return a.exec();

}

В данном листинге создается объект класса Widget - w; w.show() - загружает виджет при запуске программы; MyServer w("127.0.0.1", 2323); - создает объект сервера с портом 2323 и подключением к локальному адресу.

В функции main() обычно должны выполняться следующие пункты:

· Создание диалогового окна - клиента;

· Отправка какого-либо файла серверу;

· Принятие команды от сервера для начала моделирования сети Петри.

Рисунок 42 - Клиент

Как видно на рисунке 42, виджет имеет несколько кнопок.

Кнопка «Send» отвечает за отправку сообщений.

Кнопка «File» отвечает за отправку файлов клиенту.

Как только клиент запускается, он сразу же подключается к серверу, подтверждение можно увидеть на экране клиента. Появилась надпись «Server Response: Connected!». Значит, клиент подключен и ждет получения команды на начало моделирования от сервера.

Заключение

В ходе выполнения дипломного проекта была разработано сетевое приложения в архитектуре «клиент-сервер» на базе синтаксического анализатора xml-файлов.

Программа разработана на языке C++ в среде разработки Qt5.

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

Список использованных источников

1) Макс Шлее.Qt4.8 профессиональное программирование на С++, БХВ-Петербург, 2012. -- 893 c.

2) Что такое Qt ? - http://www.firststeps.ru/linux/qt/r.php?1

3) Телеобработка данных. Архитектура связей. - https://vunivere.ru/work74920

4) Qt википедия. https://ru.wikipedia.org/wiki/Qt

5) Уроки по Qt. https: // www.youtube.com/results?search query=%D1%83%D1%80%D0%BE%D0%BA%D0%B8+%D0%BF%D0%BE+Qt

Приложение А

Листинги программ

(Обязательное)

Приложение A.1

1

1.1 myclient.cpp:

#include "myclient.h"

MyClient::MyClient(const QString& strHost,

int nPort,

QWidget* pwgt /*=0*/

) : QWidget(pwgt)

, m_nNextBlockSize(0)

{

m_pTcpSocket = new QTcpSocket(this);

m_pTcpSocket->connectToHost(strHost, nPort);

connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected()));

connect(m_pTcpSocket, SIGNAL(readyRead()), SLOT(slotReadyRead()));

connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),

this, SLOT(slotError(QAbstractSocket::SocketError))

);

m_ptxtInfo = new QTextEdit;

m_ptxtInput = new QLineEdit;

connect(m_ptxtInput, SIGNAL(returnPressed()),

this, SLOT(slotSendToServer())

);

m_ptxtInfo->setReadOnly(true);

QPushButton* pcmd = new QPushButton("&Send");

QPushButton* fil = new QPushButton("&File");

connect(pcmd, SIGNAL(clicked()), SLOT(slotSendToServer()));

connect(fil, SIGNAL(clicked()), SLOT(fileSendToServer()));

//Layout setup

QVBoxLayout* pvbxLayout = new QVBoxLayout;

pvbxLayout->addWidget(new QLabel("<H1>Client</H1>"));

pvbxLayout->addWidget(m_ptxtInfo);

pvbxLayout->addWidget(m_ptxtInput);

pvbxLayout->addWidget(pcmd);

pvbxLayout->addWidget(fil);

setLayout(pvbxLayout);

}

void MyClient::slotReadyRead()

{

QDataStream in(m_pTcpSocket);

in.setVersion(QDataStream::Qt_4_2);

for (;;) {

if (!m_nNextBlockSize) {

if (m_pTcpSocket->bytesAvailable() < sizeof(quint16)) {

break;

}

in >> m_nNextBlockSize;

}

if (m_pTcpSocket->bytesAvailable() < m_nNextBlockSize) {

break;

}

QTime time;

QString str;

QString zap("start");

in >> time >> str;

if(str != zap)

m_ptxtInfo->append(time.toString() + " " + str);

else

{

str = "Вычисления завершены";

m_ptxtInfo->append(time.toString() + " " + str);

test1();

}

m_nNextBlockSize = 0;

}

}

void MyClient::slotError(QAbstractSocket::SocketError err)

{

QString strError =

"Error: " + (err == QAbstractSocket::HostNotFoundError ?

"The host was not found." :

err == QAbstractSocket::RemoteHostClosedError ?

"The remote host is closed." :

err == QAbstractSocket::ConnectionRefusedError ?

"The connection was refused." :

QString(m_pTcpSocket->errorString())

);

m_ptxtInfo->append(strError);

close();

}

void MyClient::slotSendToServer()

{

// QTextCodec *tcodec = QTextCodec::codecForName("Windows-1251");

// QString asd = tcodec->toUnicode(file.readAll());

QByteArray arrBlock;

QDataStream out(&arrBlock, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_4_2);

if(maxn == 0)

if(m_ptxtInput->text().isEmpty())

{

QString nump = "Проверка";

out << quint16(0) << QTime::currentTime() << nump;

}

else

out << quint16(0) << QTime::currentTime() << m_ptxtInput->text();

else

{

QString asd = QString::number(maxn);

out << quint16(0) << QTime::currentTime() << asd;

maxn = 0;

}

out.device()->seek(0);

out << quint16(arrBlock.size() - sizeof(quint16));

m_pTcpSocket->write(arrBlock);

m_ptxtInput->setText("");

}

void MyClient::slotConnected()

{

m_ptxtInfo->append("Received the connected() signal");

}

void MyClient::fileSendToServer()

{

QString fileName = QFileDialog::getOpenFileName(this,

QString::fromUtf8("Открыть файл"),

QDir::currentPath(),

"Images (*.png *.xpm *.jpg *.ui *.svg);;All files (*.*)");

fileName = fileName.replace("/","\\");

QFile file(fileName);

if (!file.open(QIODevice::ReadOnly)) // Проверяем, возможно ли открыть наш файл для чтения

return;

QByteArray asd = file.readAll();

QByteArray arrBlock;

QDataStream out(&arrBlock, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_4_2);

out << quint16(0) << QTime::currentTime() << asd;

out.device()->seek(0);

out << quint16(arrBlock.size() - sizeof(quint16));

m_pTcpSocket->write(arrBlock);

}

void MyClient::test1()

{

QTime time;

int mas[100];

int mas2 [100];

int num;

for(int i = 0; i < 10; i++)

{

qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

num = qrand()%10;

mas[i] = num;

qDebug() << mas[i];

}

for(int i = 0; i < 10; i++)

{

mas2[i] = mas[0] + mas[i];

// mas2[i] = 1;

}

maxn = mas2[0];

for(int i = 0; i < 10; i++)

{

if(maxn < mas2[i])

{

maxn = mas2[i];

}

}

maxn = num;

QString str = QString::number(maxn);

m_ptxtInfo->append(time.toString() + " " + str);

QByteArray arrBlock;

QDataStream out(&arrBlock, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_4_2);

out << quint16(0) << QTime::currentTime() << str;

out.device()->seek(0);

out << quint16(arrBlock.size() - sizeof(quint16));

m_pTcpSocket->write(arrBlock);

}

1.2 main.cpp:

#include "myclient.h"

#include <QApplication>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MyClient w("127.0.0.1", 2323);

w.show();

return a.exec();

}

1.3 myclien.h:

#ifndef MYCLIENT_H

#define MYCLIENT_H

#include <QWidget>

#include <QTcpSocket>

#include <QTextEdit>

#include <QLineEdit>

#include <QPushButton>

#include <QVBoxLayout>

#include <QTime>

#include <QLabel>

#include <QFile>

#include <QByteArray>

#include <QTextCodec>

#include <QFileDialog>

#include <QDir>

#include <QHostAddress>

#include <QDialog>

#include <QtGui>

#include <QGraphicsScene>

#include <QGraphicsView>

#include <QGraphicsRectItem>

#include <QGraphicsItemGroup>

#include <QTimer>

class QTextEdit;

class QLineEdit;

class MyClient : public QWidget {

Q_OBJECT

private:

QTcpSocket* m_pTcpSocket;

QTextEdit* m_ptxtInfo;

QLineEdit* m_ptxtInput;

quint16 m_nNextBlockSize;

int maxn = 0;

public:

MyClient(const QString& strHost, int nPort, QWidget* pwgt = 0) ;

void test1();

private slots:

void slotReadyRead ( );

void slotError (QAbstractSocket::SocketError);

void slotSendToServer( );

void slotConnected ( );

void fileSendToServer( );

};

#endif // MYCLIENT_H

1.4 graphicsscene.h:

#ifndef GRAPHICSSCENE_H

#define GRAPHICSSCENE_H

#include <QWidget>

#include <QTcpSocket>

#include <QTextEdit>

#include <QLineEdit>

#include <QPushButton>

#include <QVBoxLayout>

#include <QTime>

#include <QLabel>

#include <QFile>

#include <QByteArray>

#include <QTextCodec>

#include <QFileDialog>

#include <QDir>

#include <QHostAddress>

#include <QDialog>

#include <QtGui>

#include <QGraphicsScene>

#include <QGraphicsView>

#include <QGraphicsRectItem>

#include <QGraphicsItemGroup>

#include <QTimer>

#include <QMenu>

#include <QtSvg/QSvgGenerator>

#include <QFileDialog>

#include <QPainter>

#include "svgreader.h"

class GraphicsScene : public QWidget

{

Q_OBJECT

public:

explicit GraphicsScene(QWidget *parent = 0);

QGraphicsScene *scene;

QGraphicsView *view;

signals:

public slots:

void load1();

private slots:

void slotActivated(QAction* pAction);

private:

QMenu* m_pmnu;

void addAction();

void addScene();

QString path;

QSvgGenerator *generator;

QPainter *painter;

protected:

virtual void contextMenuEvent(QContextMenuEvent* pe)

{

m_pmnu->exec(pe->globalPos());

}

};

#endif // GRAPHICSSCENE_H

1.5 myserver.h:

#ifndef MYSERVER_H

#define MYSERVER_H

#include <QWidget>

#include <QTextEdit>

#include <QtGui>

#include <QTcpServer>

#include <QTcpSocket>

#include <QMessageBox>

#include <QVBoxLayout>

#include <QLabel>

#include <QFile>

#include "graphicsscene.h"

#include <QList>

class QTcpServer;

class QTextEdit;

class QTcpSocket;

class MyServer : public QWidget

{

Q_OBJECT

private:

QTcpServer* m_ptcpServer;

QTextEdit* m_ptxt;

quint16 m_nNextBlockSize;

QTcpSocket* socet;

QList<QTcpSocket* > lis;

QLineEdit *lineEdit;

QLineEdit *lineEdit_2;

QLineEdit *lineEdit_3;

QLineEdit *lineEdit_4;

QTextEdit *m_ptxtInfo;

QList<int> *list1;

QString maspr[3];

int socn = 1;

int answ = 0;

int a, b = 0;

int c = 0;

int prm = 0;

int kol1, kol2;

void sendToClient(QTcpSocket* pSocket, const QString& str);

public:

MyServer(int nPort, QWidget* pwgt = 0);

QTimer* timer;

GraphicsScene *scen1;

static QList<QGraphicsRectItem *> getElements(const QString filename);

public slots:

virtual void slotNewConnection();

void slotReadClient ();

void slotWriteClient ();

void slotZad ();

void xmlLoad ();

void xmlRead ();

void set_Cond();

};

#endif // MYSERVER_H

1.6 svgreader.h:

#ifndef SVGREADER_H

#define SVGREADER_H

#include <QList>

#include <QGraphicsRectItem>

class SvgReader

{

public:

SvgReader();

static QList<QGraphicsRectItem *> getElements(const QString filename);

static QRectF getSizes(const QString filename);

};

#endif // SVGREADER_H

1.7 graphicsscene.cpp:

#include "graphicsscene.h"

GraphicsScene::GraphicsScene(QWidget *parent) : QWidget(parent)

{

addScene();

addAction();

show();

}

//static int randomBetween(int low, int high)

//{

// return (qrand() % ((high + 1) - low) + low);

//}

void GraphicsScene::addScene()

{

QGridLayout* pvbxLayout = new QGridLayout();

scene = new QGraphicsScene(QRectF(0, 0, 300, 300));

view = new QGraphicsView();

view->setMinimumSize(500,500);

view->setScene(scene);

pvbxLayout->addWidget(view);

setLayout(pvbxLayout);

}

void GraphicsScene::slotActivated(QAction* pAction)

{

qDebug() << pAction->text();

}

void GraphicsScene::addAction()

{

m_pmnu = new QMenu(this);

m_pmnu->addAction(QString("Загрузить"), this, SLOT(load1()));

connect(m_pmnu, SIGNAL(triggered(QAction*)), SLOT(slotActivated(QAction*)));

}

void GraphicsScene::load1()

{

QString newPath = QFileDialog::getOpenFileName(this, trUtf8("Open SVG"),

path, tr("SVG files (*.svg *.ui)"));

if (newPath.isEmpty())

return;

path = newPath;

scene->clear();

scene->setSceneRect(SvgReader::getSizes(path)); // Зададим размеры графической сцены

// Установим на графическую сцену объекты, получив их с помощью метода getElements

foreach (QGraphicsRectItem *item, SvgReader::getElements(path)) {

QGraphicsRectItem *rect = item;

scene->addItem(rect);

}

}

1.8 main.cpp:

#include "myserver.h"

#include <QApplication>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MyServer w(2323);

w.show();

return a.exec();

}

1.9 myserver.cpp:

#include "myserver.h"

#include <QApplication>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

MyServer w(2323);

w.show();

return a.exec();

}

#include "myserver.h"

#include <QLineEdit>

#include <QCheckBox>

#include <QDomDocument>

#include <QSplitter>

#include <QTableWidget>

MyServer::MyServer(int nPort, QWidget* pwgt /*=0*/) : QWidget(pwgt)

, m_nNextBlockSize(0)

{

m_ptcpServer = new QTcpServer(this);

if (!m_ptcpServer->listen(QHostAddress::Any, nPort)) {

QMessageBox::critical(0,

"Server Error",

"Unable to start the server:"

+ m_ptcpServer->errorString()

);

m_ptcpServer->close();

return;

}

connect(m_ptcpServer, SIGNAL(newConnection()), this, SLOT(slotNewConnection())

);

m_ptxt = new QTextEdit;

lineEdit_4 = new QLineEdit;

m_ptxt->setReadOnly(true);

//Layout setup

QPushButton* wCl = new QPushButton("&Send");

connect(wCl, SIGNAL(clicked()), SLOT(slotWriteClient()));

QPushButton* xmlf = new QPushButton("&XML_SVG");

connect(xmlf, SIGNAL(clicked()), SLOT(xmlLoad()));

QPushButton* xmr = new QPushButton("&XML");

connect(xmr, SIGNAL(clicked()), SLOT(xmlRead()));

QPushButton* setC = new QPushButton("&Set_C");

connect(setC, SIGNAL(clicked()), SLOT(set_Cond()));

QVBoxLayout* pvbxLayout = new QVBoxLayout;

pvbxLayout->addWidget(new QLabel("<H1>Server</H1>"));

pvbxLayout->addWidget(m_ptxt);

pvbxLayout->addWidget(lineEdit_4);

pvbxLayout->addWidget(wCl);

pvbxLayout->addWidget(xmlf);

pvbxLayout->addWidget(xmr);

pvbxLayout->addWidget(setC);

setWindowTitle("Server");

setLayout(pvbxLayout);

}

/*virtual*/ void MyServer::slotNewConnection()

{

QTcpSocket* pClientSocket = m_ptcpServer->nextPendingConnection();

connect(pClientSocket, SIGNAL(disconnected()),

pClientSocket, SLOT(deleteLater())

);

connect(pClientSocket, SIGNAL(readyRead()),

this, SLOT(slotReadClient())

);

sendToClient(pClientSocket, "Server Response: Connected!");

m_ptxt->append("Client Response: Connected!");

}

void MyServer::slotReadClient()

{

QTcpSocket* pClientSocket = (QTcpSocket*)sender();

QDataStream in(pClientSocket);

in.setVersion(QDataStream::Qt_4_2);

for (;;) {

if (!m_nNextBlockSize) {

if (pClientSocket->bytesAvailable() < sizeof(quint16)) {

break;

}

in >> m_nNextBlockSize;

}

if (pClientSocket->bytesAvailable() < m_nNextBlockSize) {

break;

}

QTime time;

QString str;

in >> time >> str;

QString strMessage =

time.toString() + " " + "Client has sended - " + str;

m_ptxt->append(strMessage);

m_nNextBlockSize = 0;

if(answ == 1)

{

a = str.toInt();

if((lineEdit_4->text() == "start" && (a >= 0 )) /*&& (kol2 != NULL)*/)

{

maspr[prm] = QString::number(a);

if(2>prm)

prm++;

else

prm = 0;

}

if(a > b)

{

b = a;

}

}

if(lineEdit_4->text() != "start")

{

lis.append(pClientSocket);

for(int i = 0; i < lis.length(); i++)

{

for(int j = 0; j < lis.length(); j++)

{

if(i != j)

{

if(lis.at(i) == lis.at(j))

lis.removeAt(i);

}

}

}

}

}

}

void MyServer::sendToClient(QTcpSocket* pSocket, const QString& str)

{

QByteArray arrBlock;

QDataStream out(&arrBlock, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_4_2);

out << quint16(0) << QTime::currentTime() << str;

out.device()->seek(0);


Подобные документы

  • Многоуровневые архитектуры клиент–сервер. Диаграммы классов, реализующих уровни презентации, бизнес–логики и базы данных приложения. Словесное описание процесса выполнения транзакций. Создание, изменение и удаление хранимых процедур, их выполнение.

    курсовая работа [3,4 M], добавлен 23.03.2013

  • Разработка клиент-серверного приложения, позволяющего взаимодействовать друг с другом с использованием доступа к базам данных. Проектирование связи сервера с базой данных с помощью технологии ODBC. Разработка интерфейса программы, ее тестирование.

    курсовая работа [352,0 K], добавлен 24.08.2016

  • Основные концепции разработки приложения в архитектуре MVVM. Проектирование базы данных, предназначенной для сбора информации о дорожно-транспортных происшествиях. Классификация и типы архитектуры "клиент–сервер", ее основные достоинства и недостатки.

    курсовая работа [4,1 M], добавлен 25.11.2015

  • Реализация прямого проектирования в архитектуре "файл-сервер". Процесс изменения структуры базы данных, реализация прямого проектирования в архитектуре "клиент-сервер", генерирование SQL-кода создания базы данных на основе физической модели данных.

    контрольная работа [697,8 K], добавлен 16.02.2015

  • Основные компоненты системы и управление ими. Распределенная система управления и человеко-машинный интерфейс. Инструментарий для создания OPC-серверов и OPC-клиентов. Техническое руководство для администраторов, обслуживающих OPC-клиент и веб-сервер.

    дипломная работа [2,0 M], добавлен 20.10.2011

  • Реализация информационной системы "Стройгенплан" в архитектуре "клиент-сервер". Цели и задачи моделируемой информационной системы, ее функциональная и информационная модели. Описание программного обеспечения, разработанного в архитектуре "клиент-сервер".

    курсовая работа [1,9 M], добавлен 30.08.2010

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

    курсовая работа [28,5 K], добавлен 28.06.2011

  • Основные технологии веб-программирования. Методы отправки данных на сервер с помощью HTML-формы. PHP - Препроцессор Гипертекста. Сохранение данных в базе данных MySQL. Клиент-Сервер и технология CGI. Примеры использования PHP совместно с MySQL.

    лекция [2,9 M], добавлен 27.04.2009

  • Анализ предметной области. Выработка требований и ограничений. Серверная часть информационной системы. Запросы клиентского приложения. Триггеры для поддержки сложных ограничений целостности в базе данных. Пользовательский интерфейс клиентского приложения.

    курсовая работа [2,6 M], добавлен 21.02.2016

  • Характеристика модели клиент-сервер как технологии взаимодействия в информационной сети. Разработка и описание алгоритмов работы приложений на платформе Win32 в среде Microsoft Visual Studio, использующих для межпроцессного взаимодействия сокеты.

    курсовая работа [544,6 K], добавлен 02.06.2014

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.