Автор работы: Пользователь скрыл имя, 14 Февраля 2013 в 21:48, дипломная работа
Метою дослідження є перевірка навичок програмування на QT, отримання розробленої системи автоматичного мережевого розподілення навчального матеріалу у комп’ютерному класі з урахуванням IP-адрес комп’ютерів й інструкції з її використання та закріплення знань, отриманих в процесі теоретичної діяльності.
Задачі дослідження наступні:
Робота над програмним продуктом та реалізацією програмного забезпечення;
Застосування знань про мережну роботу засобами QT;
Застосування знань про маніпулювання файловою системою й роботою з нею засобами QT;
Отримання нового досвіду з проектування на платформі QT;
ВСТУП 6
РОЗДІЛ 1. АНАЛІЗ ДЖЕРЕЛ СТОСОВНО МЕТОДІВ РОЗРОБКИ 9
Вибір середи програмування 9
Технологія клієнт – сервер: взаємодія клієнта з сервером 11
Робота з мережею засобами QT 13
Використання TCP за допомогою класів QTcpSocket та QTcpServer 14
Робота з файловою системою засобами QT 16
Клас QFileSystemModel 17
Клас QDir. Перегляд вмісту директорії за допомогою QDir 17
Клас QFile 19
Клас QFileInfo 20
Робота з потоками засобами QT 21
Клас QThread 22
Класи QRunnable та QThreadPool 24
Клас QtConcurrent 24
РОЗДІЛ 2. ОСНОВНІ ПРОБЛЕМИ РОЗРОБКИ ТА ЇХ РІШЕННЯ 26
Мета розробки 26
Основні задачі та проблеми 26
Крос-платформність 27
Робота з мережею: захист від збоїв 28
Власний протокол взаємодії клієнта з сервером 29
Маніпулювання файловою системою 30
Алгоритм роботи програми 32
Алгоритм роботи сервера 32
Алгоритм роботи клієнта 34
Алгоритм роботи графічного клієнта 35
РОЗДІЛ 3.РЕАЛІЗАЦІЯ СИСТЕМИ АВТОМАТИЧНОГО МЕРЕЖЕВОГО РОЗПОДІЛЕННЯ НАВЧАЛЬНОГО МАТЕРІАЛУ У КОМПЬЮТЕРНОМУ КЛАСІ 36
Програмна реалізація сервера 38
Програмна реалізація клієнта 40
Програмна реалізація графічного клієнта 42
Інструкція з використання програми 44
РОЗДІЛ 4. ОХОРОНА ПРАЦІ 48
Основні поняття охорони праці 48
Загальні положення 50
Вимоги до виробничого персоналу 51
Вимоги безпеки під час роботи 53
Вимоги безпеки в аварійних ситуаціях 54
Інструкція із заходів пожежної безпеки є службових кабінетах і лабораторіях 55
Загальні положення 55
Співробітники зобов'язані 55
Забороняється 55
Дії при пожежі 55
Обов'язки особи, відповідального за протипожежний стан приміщення 56
Відповідальність особи, відповідального за протипожежний стан приміщенні 56
ВИСНОВКИ 57
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ 59
Різні платформи
мають різні способи
Для цих цілей клас надає цілий ряд статичних методів (Таблиця 1.2):
Таблиця 1.2
Методи |
Опис |
QDir::current() |
повертає шлях директорії програми |
QDir::root() |
повертає root – директорію |
QDir::drives() |
повертає перелік списоку об'єктів класу |
QDir::home() |
повертає персональну директорію користувача |
Клас QDir не надає методів для визначення поточного каталогу програми. Але якщо вам потрібно визначити, з якого каталогу було запущено програму, то слід скористатися методом QApplication :: applicationDirPath(), або QApplication :: applicationFilePath(), що повертає, в додаток до всього, і назву програми.
Існування директорії можна перевірити за допомогою методу exists(). Щоб переміщатися по директоріях, можна використовувати метод cd(), який приймає, як параметр, абсолютний шлях директорії, і cdUp(). Виклик cd("..") відповідає виклику методу cdUp().
Для конвертації відносного шляху директорії в абсолютний можна викликати метод makeAbsolute ().
Для створення директорії потрібно викликати метод mkdir(). В разі успішного проведення цієї операції метод поверне значення true, в разі невдачі – false.
Якщо
вам потрібно перейменувати директорію,
то скористайтеся методом rename()
Видалення директорій проводиться методом rmdir(), який отримує шлях, і в разі успіху повертає true, а в разі невдачі – false.
За допомогою класу QDir можна одержати вміст вказаної директорії. При цьому допускається застосування різних фільтрів, щоб виключити зі списку файли, які не цікавлять Вас. Для цих цілей в класі визначено методи entryList() і entryInfoList(). Перший повертає список імен елементів (QStringList), а другий – інформаційний список (QFileInfoList). Якщо вам потрібно дізнатися тільки кількість елементів, що знаходяться в директорії, то просто викличте метод count().
Процес пошуку заданих файлів може бути тривалим, що може привести до "завмирання" графічного інтерфейсу програми. Тому, для подавлення цього небажаного ефекту, при кожному виклику методу скористайтеся методом QApplication :: processEvent.
Клас QFile успадкований від класу QIODevice. У ньому містяться методи для роботи з файлами: відкриття, закриття, читання та запису даних. Створити об'єкт можна, передавши в конструкторі рядок, що містить ім'я файлу. Можна нічого не передавати в конструкторі, а зробити це після створення об'єкту, викликом методу setName().
В процесі роботи з файлами іноді потрібно дізнатися, відкритий файл чи ні. Для цього викликається метод QIODevice :: IsOpen(), який поверне true, в тому випадку, якщо файл відкритий, інакше – false. Щоб закрити файл, потрібно викликати метод close(). Із закриттям виробиться запис всіх даних буфера. Якщо потрібно зробити запис даних буфера в файл без його закриття, то викликається метод QFile :: flush().
Перевірити, чи існує потрібний вам файл, можна статичним методом QFile :: exists(). Цей метод приймає рядок, що містить повний чи відносний шлях до файлу. Якщо файл знайдений, то метод поверне true, в іншому випадку – false. Для проведення цієї операції існує і нестатичні метод QFile :: exists(). Методи QIODevice :: read() і QIODevice :: write() дозволяють зчитувати і записувати файли блоками.
Якщо потрібно зчитати або записати дані за один раз, то використовують методи QIODevice :: write() і QIODevice :: readAll(). Всі дані можна зчитати в об'єкт класу QByteArray, а потім записати з нього в інший файл.
Операція зчитування всіх даних відразу, залежно від розміру файлу, може зайняти багато оперативної пам'яті, а значить, до цього слід прибігати тільки у випадках гострої необхідності або в тому випадку, коли файли займають мало місця. Витрата пам'яті при зчитуванні відразу всього файлу можна значно скоротити за тієї умови, що файл містить надлишкову інформацію. Тоді можна скористатися функціями стиснення qCompress() і qUncompress(), які визначені разом з класом QByteArray. Ці функції отримують, як аргумент, об'єкт класу QByteArray і повертають, як результат, новий об'єкт класу QByteArray.
Для видалення файлу клас QFile містить статичний метод remove(). В цей метод необхідно передати рядок, що містить повний чи відносний шлях видаляємого файлу.
Завдання цього класу полягає в наданні інформації про властивості файла, наприклад: ім'я, розмір, час останньої зміни, права доступу і т.д. Об'єкт класу QFileInfo створюється передачею в його конструктор шляху до файлу, але можна передавати і об'єкти класу QFile.
Іноді необхідно переконатися, що досліджуваний об'єкт є каталогом, а не файлом і навпаки. Для цієї мети існують методи isFile() і isDir().
У тому випадку, якщо об'єкт є файлом, метод isFile() повертає значення булевого типу true, інакше – false. Якщо об'єкт є директорією, то метод isDir() повертає true, інакше – false. Крім цих методів, клас QFileInfo містить метод isSymLink(), який повертає true, якщо об'єкт є символічним посиланням (symbolic link або shortcut в ОС Windows).
Символьні посилання застосовуються в UNIX для забезпечення зв'язку з файлами або каталогами. Створюються вони за допомогою команди "ln" з ключем "-s".
Щоб отримати шлях до файлу, потрібно скористатися методом absoluteFilePath(). Для отримання відносного шляху до файлу слід використовувати метод filePath(). Для отримання імені файлу потрібно викликати метод fileName(), який повертає ім'я файлу разом з його розширенням. Якщо потрібно тільки ім'я файлу, то слід викликати метод baseName(). Для отримання розширення використовується метод completeSuffix().
Іноді потрібно дізнатися час створення файла, час його останньої зміни або читання. Для цього клас QFileInfo надає методи created(), lastModified() і lastRead() відповідно. Ці методи повертають об'єкти класу QDateTime, які можна перетворити в рядок методом toString().
Атрибути файлу дають інформацію про те, які операції можна проводити з файлом.
Для їх отримання в класі QFileInfо існують наступні методи (Таблиця 1.3):
Таблиця 1.3
Методи |
Опис |
isReadable() |
повертає true, якщо із зазначеного файлу можна читати інформацію |
isWriteable() |
повертає true, якщо в зазначений файл можна записувати інформацію |
isHidden() |
повертає true, якщо зазначений файл є прихованим |
isExecutable() |
повертає true, якщо зазначений файл можна виконувати. В ОС UNIX це визначається не на підставі розширення файлу, як в DOS і ОС Windows, а за допомогою властивостей самого файлу. |
Метод size() класу QFileInfо повертає розмір файлу в байтах. Розмір файлів рідко відображається в байтах, частіше використовуються спеціальні буквені позначення, що повідомляють про його розміри. Наприклад, для кілобайти – це буква К, для мегабайта – М, для гігабайти – G, а для терабайта – Т.
Термінологія QT
QThread основний,
низькорівневий клас для
Для того, щоб запустити код в потоці, використовуючи QThread, ми повинні його успадкувати і перевантажити метод QThread :: run() або, починаючи з QT 4.4., QThread::exec().
Основний цикл обробки подій тільки один на потік, викликається він main() і запускається з QСoreApplication :: exec(). Він ще має назву потока GUI, тому що операції, пов'язані з графічним інтерфейсом, доступні тільки в цьому потоці. Локальний обробник подій QThread можна запустити не викликаючи QThread :: exec(), всередині методу run().
Так само, як і у QCoreApplication, у QThread є методи QThread :: quit () і QThread :: exit () для зупинки циклу обробки подій.
Цикл обробки подій потоку доставляє події всіх об'єктаv QObject, які знаходяться в цьому потоці, це всі об'єкти, які були створені в цьому потоці або ті, які були переміщені в цей потік. Можна сказати, що потоки і QObject зв'язуються, в сенсі, що об'єкти живуть в своїх потоках. Це стосується до об'єктів, які конструюються в конструкторі об'єкта QThread.
В будь-який момент часу ми можемо дізнатися, якому потоку належить QObject, викликавши метод QObject :: thread(). Варто звернути увагу, що всі QObject, створені до QCoreApplication – це об'єкти, які не пов'язані з потоком, іншими словами, QCoreApplication створює об'єкт QThread, який і буде головним потоком (див.рис. 1.3).
Рис. 1.3 - Потоки
Ми можемо
використовувати
Дуже
важливо зрозуміти, що QObject і всі
класи, спадкоємці не є потокобезпечними.
Тому, ви не можете отримати доступ до
QObject із декількох потоків одночасно,
якщо звичайно ви не серіалізуєте доступ
до внутрішніх даних об'єкта. Метод
QObject :: deleteLater(), коли хочете видалити QObject
з іншого потоку, який надішле повідомлення,
завдяки якому видалення
Більш того, QWidget і всі його спадкоємці, на ряду з іншими класами GUI не є реєнтерабельними: їх можна використовувати тільки з GUI потоків.
Можна змінити приналежність об'єкта, викликавши QObject :: moveToThrea (),при цьому зміниться не тільки належність об'єкта, але і його нащадків. Так як QObject не потокобезпечний клас, ми повинні використовувати його лише в тому потоці, в якому він знаходиться, тому, ви можете тільки відправити об'єкт з потоку, в якому він знаходиться в інший потік, а не навпаки, з іншого потоку забрати або перемістити об'єкт . Більш того, QT зобов'язує, що б всі нащадки QObject обов'язково знаходилися в тому ж потоці, в якому знаходиться предок.
QT так
само вимагає, що б всі об'
QRunnable – це невеликий абстрактний клас, який можна використовувати для запуску завдання в іншому потоці в стилі «запустив і забув». Все що нам необхідно зробити, так це успадкувати QRunnable і написати реалізацію його чисто віртуального методу run().
Насправді, коли ми запускаємо об'єкт QRunnable, ми використовуємо клас QThreadPool, який управляє пулом потоків. Викликавши QThreadPool :: start(runnable) ми відправляємо QRunnable в чергу завдань QThreadPool. Як тільки потік стане доступним, QRunnable буде вилучений і запущений в цьому потоці. У всіх додатків QT є глобальний пул потоків, до якого можна отримати доступ, викликавши QThreadPool :: globalInstance(), але завжди можна створити закритий примірник QThreadPool і керувати ним явно.
Зверніть увагу, що QRunnable не успадковується від QObject, тим самим не має вбудованих засобів для з'єднання з іншими компонентами, ви можете зробити їх самостійно, використовуючи низькорівневі потокові примітиви (черги для зберігання результатів, захищені мютексом та ін.).
QtConcurrent
– це високорівневе API, побудоване
на базі QThreadPool, яке використовується
для реалізації розповсюджених
шаблонів паралельного
На відміну від QThread і QRunnable, QtConcurrent не вимагає низькорівневих примітивів синхронізації. Замість них, всі методи QtConcurrent повертають об'єкти QFuture, які можна використовувати для запиту стану обчислення, зупинки / продовження / скасування обчислень, а так само містять результати обчислень. Клас QFutureWatcher можна використовувати для спостереження за станом QFuture і взаємодіяти з ним за допомогою механізму сигналів і слотів.
РОЗДІЛ 2
ОСНОВНІ ПРОБЛЕМИ РОЗРОБКИ
ТА ЇХ РІШЕННЯ
Розроблювану систему можна поділити на три частини: сервер, клієнт та графічний клієнт. Мета кожної з частин – маніпулювання файловою системою.
Головною задачею сервера є відстеження нових підключень клієнтів та обробка інформації, отриманої від клієнтів.
Информация о работе Розробка системи автоматизованого мережевого розподілення навчального матеріалу