Реферат Баранский И. В
Скачать 466.2 Kb.
|
Стоит учитывать, что Веб-программирование – это частный случай программирования клиент-серверного приложения [11]. Клиентом в веб-приложении выступает браузер, а сервером – веб-сервер что дает ряд плюсов: Низкая стоимость внедрения; Очень простая поддержка; Независимость от Операционной системы; Доступность из любой точки мира. веб-программировании обычно используют JavaScript на стороне клиента, а на стороне сервера могут быть как один или несколько языков программирования: PHP, Java, C++, C, JavaScript, ASP.NET, Python и другие. Создание рабочего прототипа. Процесс создания прототипа обычно состоит из шагов: Определение начальных требований; Разработка первого варианта прототипа, который содержит только пользовательский интерфейс системы; Изучение прототипа заказчиком и конечными пользователями, получение обратной связи о необходимых изменениях и дополнениях; Переработка и улучшение прототипа: с учетом полученных замечаний и предложений изменяются как спецификации, так и прототип, после этого шаги 3 и 4 могут повторяться. Прототипы дают возможность глубже вникнуть в проблему и принять все необходимые проектные решения еще на ранних этапах проектирования []. Тестирование. Для клиент-серверных приложений тестирование можноусловно разделить на два уровня: Серверный; Клиентский. На первом (серверном) уровне, тестируется взаимодействие выпускаемого программного обеспечения с окружением, в которое оно будет установлено: Аппаратные средства (тип и количество процессоров, объем памяти, характеристики сети / сетевых адаптеров и т.д.); Программные средства (ОС, драйвера и библиотеки, стороннее ПО, влияющее на работу приложения и т.д.); Основной упор здесь делается на тестирование с целью определения оптимальной конфигурации оборудования, удовлетворяющего требуемым характеристикам качества (эффективность, портативность, удобство сопровождения, надежность). На клиентском уровне, программное обеспечение тестируется с позиции его конечного пользователя и конфигурации его рабочей станции. На этом этапе будут протестированы следующие характеристики: удобство использования, функциональность. Для этого необходимо будет провести ряд тестов с различными конфигурациями рабочих станций: Тип, версия и битность операционной системы (подобный вид тестирования называется кроссплатформенное тестирование); Тип и версия Web барузера, в случае если тестируется Web приложение (подобный вид тестирования называется кросс-браузерное тестирование); Тип и модель видео адаптера (при тестировании игр это очень важно); Версии драйверов, библиотек и т.д. (для JAVA приложений версия JAVA машины очень важна, тоже можно сказать и для .NET приложений касательно версии .NET библиотеки); и т.д. Уже на начальном этапе становится очевидно, что чем больше требований к работе приложения при различных конфигурациях рабочих станций, тем больше тестов нам необходимо будет провести. В связи с этим, рекомендуем, по возможности, автоматизировать этот процесс, так как именно при конфигурационном тестировании автоматизация реально помогает сэкономить время и ресурсы. Конечно же автоматизированное тестирование не является панацеей, но в данном случае оно окажется очень эффективным помощником. Релиз и дальнейшая поддержка. Стабильная версия программы, готовая к использованию по её назначению, прошедшая тестирования, в которых исправлены основные ошибки, но существует вероятность появления новых, ранее не замеченных, ошибок. 2.2 Разработка клиент-серверного приложения Для создания клиент-серверного приложения была выбрана двухуровневая архитектура и объектно-ориентированный язык программирования – Java, для написание всей программы. Вся обработка данных происходит на сервере. Двухуровневая архитектура легко реализуема и не требует каких-либо финансовых вложений. Структурная модель строилась так что даже после релиза можно относительно легко добавлять новый функционал. Рисунок 7. Структурная модель многопользовательского приложения «Chat» Взаимодействие серверного интерфейса и клиентов происходит через потокозащищённый HashMap содержащий всю информацию о клиентах. Наиболее значимыми являются код взаимодействия клиента и сервера. private void Handling() { while (true) { try { Socket client = server.accept(); new ClientHandler(client,KeyAES).start(); //Если клиент успешно установил соединение передаем его обработчику //клиентов, а также ключ которым шифруются данные. } catch (IOException e1) { e1.printStackTrace(); } try { //после проверки данных в потоке засыпаем на 10 миллисекунд. Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.security.Key; import java.security.KeyFactory; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; class ClientHandler extends Thread { //на сервере private final Socket client; private String name = "Неизвестный"; private String value; private Cipher decrypter_AES; private Cipher encrypter_AES; private Cipher encrypter_RSA; private Key KeyAES; public ClientHandler(Socket client, Key KeyAES) { this.client = client; this.KeyAES = KeyAES; try { //создаем фабрики шифрования/расшифровки //алгоритмов decrypter_AES = Cipher.getInstance("AES"); encrypter_AES = Cipher.getInstance("AES"); encrypter_RSA = Cipher.getInstance("RSA"); encrypter_AES.init(Cipher.ENCRYPT_MODE, KeyAES); decrypter_AES.init(Cipher.DECRYPT_MODE, KeyAES); } catch (Exception e) { System.err.println("Ошибка шифрования"); } } @Override public void run() { try { DataInputStream in = new DataInputStream(client.getInputStream()); while (true) { if (in.available() > 0) { //Если в потоке есть данные читаем их. short id = in.readShort(); //id пакета switch (id) { // в зависимости он полученного id создаем класс с реализацией чтения и записи данных данного пакета. case 1: { MesPacket M; int size = in.readInt(); int lenByte = in.readInt(); byte[] b = new byte[lenByte]; in.read(b); String message = new String (decrypter_AES.doFinal(b)); message = name + " : " + message; if (size > 0) { int[][] arrSmil = new int[size][2]; for (int i = 0; i < size; i++) { arrSmil[i][0] = in.readInt()+3+name.length(); arrSmil[i][1] = in.readInt(); } M = new MesPacket(encrypter_AES.doFinal(message.getBytes()), arrSmil); } else = new MesPacket(encrypter_AES.doFinal(message.getBytes())); M.readAll(); break; } case 3: { AuthorizePacket AP = new AuthorizePacket(); AP.read(in); switch (AP.getSost()) { case 1: { Cipher encrypter_RSA = Cipher.getInstance("RSA"); KeyFactory kf = KeyFactory.getInstance("RSA"); encrypter_RSA.init(Cipher.ENCRYPT_MODE,kf.generatePublic(new X509EncodedKeySpec(AP.getKey()))); AP.setKey(encrypter_RSA.doFinal(KeyAES.getEncoded())); sendPacket(AP,client); break; } case 2:{ name = AP.getName(); if (AP.getCheck().equals("ВсеОк")){ value = name+ IP: "+client.getInetAddress().getLocalHost().getHostAddress().toString(); Server.csls.put(value, client); MesPacket M = new MesPacket(encrypter_AES.doFinal((""+name + " вошел в чат"+"").getBytes())); M.readAll(); break; } AP.setSost((short)3); sendPacket(AP,client); close(); } default: { MesPacket M = new MesPacket(encrypter_AES.doFinal((""+name + " вышел из чата"+"").getBytes())); M.readAll(); close(); break; } } break; } } } else Thread.sleep(10); } } catch (Exception e) { System.err.println("Отключение"+name); close(); } } Подключение к серверу (на клиенте): private void Start() { try { TextChat.getDocument().insertString(TextChat.getDocument().getLengt h(), "Идет подключение..." + "\n", null); socket = new Socket(sip, 9322); //обработка в случае успешного соединения с сервером. handle(); } catch (Exception e) { try { TextChat.getDocument().insertString(TextChat.getDocument().getLengt h(), "Не удалось подключиться к серверу, закройте приложение" + "\n", null); } catch (BadLocationException e1) { System.exit(0); } } } public static void sendPacket (AbsPacket P,Socket s){ DataOutputStream out; try { out = new DataOutputStream(s.getOutputStream()); out.writeShort(P.GetId()); //считываем id пакета и пишем P.write(out); out.flush(); } catch (IOException e) { try { s.close(); } catch (IOException e1) { } System.out.println("Закрытие потока"); } } public void close() { Server.csls.remove(value); interrupt(); } } public void readPacket() { //на клиенте try { short id = in.readShort(); switch (id) { case 1: { try { int size = in.readInt(); int lenByte = in.readInt(); byte[] b = new byte[lenByte]; in.read(b); int sh = 0; String a = new String (decrypter_AES.doFinal(b)); StringBuffer buf = new StringBuffer(a); HTMLEditorKit kit = (HTMLEditorKit) TextChat.getEditorKit(); if (size > 0) for (int i = 0; i < size; i++) { int C = in.readInt() + sh; int S = in.readInt(); buf.replace(C - 1, C, ""); System.out.println("buf = " + buf); sh += 24 + listPathIm[S].length(); } kit.insertHTML((HTMLDocument) TextChat.getDocument(), TextChat.getDocument().getLength(), "[" + formating.format(System.currentTimeMillis()) + "] " + buf, 0, 0, null); panel.updateUI(); } catch (BadLocationException e) { } break; } case 3: { AuthorizePacket AP = new AuthorizePacket(); AP.read(in); if (AP.getSost() == 1) { Cipher decriptCipher = Cipher.getInstance("RSA"); decriptCipher.init(Cipher.DECRYPT_MODE, kP.getPrivate()); SecretKey Key = new SecretKeySpec(decriptCipher.doFinal(AP.getKey()), "AES"); encrypter_AES.init(Cipher.ENCRYPT_MODE, Key); decrypter_AES.init(Cipher.DECRYPT_MODE, Key); AP.setSost((short) 2); AP.setName(name); sendPacket(AP); } else { TextChat.getDocument().insertString(TextChat.getDocument().getLengt h(), "Ошибка аутентификации, закройте приложение" + "\n", null); } } } } catch (Exception e) { e.printStackTrace(); } } private void handle() { //на клиенте try { out = new DataOutputStream(socket.getOutputStream()); in = new DataInputStream(socket.getInputStream()); sendPacket(new AuthorizePacket(kP.getPublic().getEncoded(),(short)1)); while (true) { if (in.available() > 0) readPacket(); else try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } catch (Exception e) { System.err.println("Ошибка чтения/передачи"); close(); e.printStackTrace(); } } Каждый пакет данных пересылающийся клиентом или сервером присваивается свой id. Это позволяет структурировать разного рода, типа информацию. Java, строгий язык на котором можно решать в принципе любую задачу, благодаря кроссплатформенности может работать на разных платформах что очень важно для клиентской части. Алгоритм работы системы программы выглядит следующим образом: Сервер подключается к порту на хосте и ждет соединения с клиентом; Клиент создает сокет и пытается соединить его с портом на хосте; Если создание сокета прошло успешно, то сервер переходит в режим ожидания команд от клиента; Клиент формирует команду и передает ее серверу, переходит в режим ожидания ответа; Сервер принимает команду, выполняет ее и пересылает ответ клиенту; Клиент обрабатывает полученную информацию и выводит её пользователю в удобном виде, для её восприятия. Пока клиент или сервер не разорвет соединение смотреть пункт 4. Приложение объединяет в себе два режима: Режим сервера: Запускает сервер на порту 9322. Представляет с собой окно со списком подключившихся к нему клиентов. В верхней части окна отображается IP адрес по которому клиенты имеют возможность подключиться; Режим клиента: открывается окно в котором нужно ввести IP сервера и “nickname” который должен состоять от 5 до 15 латинских, русских символов или цифр. При создании сервера генерируется симметричный ключ алгоритмом AES этим ключом сервер шифрует всю информацию, передаваемую клиентам. Для получения этого ключа клиент при подключении к серверу генерирует у себя парный ключ (публичный и приватный) алгоритмом RSA. Рисунок 8. Главное меню Рисунок 9. Подключение к серверу Рисунок 10. Режим клиента Рисунок 11. Режим сервера Разработанное приложение работает везде где можно установить Java Runtime Environment 7 или выше. Имеет хорошую степень защиты информации т.к использует алгоритм AES, принятый в качестве стандарта шифрования правительством США в 2001 году. 2.3 Результаты апробации Для реализации апробации было проведено тестирование приложения в компании «ТехНик». Для выявления ошибок была создана анкета с вопросами, которая заполнялась после тестирования приложения. Анкета 1. Результаты тестирования приложения ОС с который вы запускали данное приложение: Windows Linux Mac OS X Другое:_____________ Были ошибки во время работы приложения, если да, то какие? Развернутый ответ:________________________________ Удобный интерфейс? Да Нет Оцените приложение по шкале от 1 до 5 Пожелания для улучшения дизайна/работы приложения Развернутый ответ:________________________________ Результаты тестирования показали следующее: Игра была установлена и работала под разными версиями операционных систем (Рисунок 14); Ошибки во время работы приложения небыли обнаружены; Интерфейс посчитали удобным 95,5% тестируемых (Рисунок 12); Рисунок 12. Оценка удобства интерфейса Средняя оценка приложения составила: 4,59 (Рисунок 13); Рисунок 13. Оценка работоспособности и устойчивости приложения Все пожелания были учтены, приложение доработано за несколько дней. Рисунок 14. Платформы, на которых протестирована работа приложения По результатам анкетирования критических багов не обнаружено. Найденные ошибки были исправлены в следующей версии, как пожелания и замечания тестировщиков. |