Пояснительная записка (1231620), страница 5
Текст из файла (страница 5)
– 0x2 – двоичные данные;
– 0x3-0x7 – зарезервированы для будущих фреймов с данными;
– 0x8 – закрытие соединения этим фреймом;
– 0x9 – PING (запрос сервера на проверку отклика от клиента);
– 0xA – PONG (ответ клинта на запрос PING сервера);
– 0xB-0x F – зарезервированы для будущих управляющих фреймов;
– 0x0 – фрейм-продолжение для фрагментированного сообщения. Он интерпретируется, исходя из ближайшего предыдущего ненулевого типа.
Если значение поле «Длина тела сообщения» лежит в интервале 0-125, то оно обозначает длину тела. Если 126, то следующие 2 байта содержат длину тела в 16-битном формате. Если 127, то следующие 8 байт содержат длину в 64-битном формате. Такая схема используется, чтобы уменьшить накладные расходы: для сообщений менее 126 байт хранение длины потребует всего 7 битов, для больших (до 65536) – 2 байта, ну а для ещё больших 8 байт. 8 байт достаточно для того чтобы передать около 2305 ПБайт (2,3 Эксабайта) данных.
Замечательным достоинством данной системы является возможность фрагментации данных. Фрагментация используется для передачи информации большого размера (различные файлы: программы, видео, аудиоданные и прочее), а также при длительных выборках из базы данных, т.е. если сервер нашел некоторую информацию по запросу пользователя он может не дожидаясь окончания поиска отправить результаты клиенту. Для фрагментирования данных необходимо:
– у всех фрагментированных фреймов, кроме последнего, установить бит FIN=0;
– поле «Опкод» указывается только у первого фрагмента, у остальных устанавливается в 0x0.
В современных версиях браузеров, реализация WebSockets уже внесена в функционал, поэтому программирование на стороне клиента минимальна и сосредоточена только на самых индивидуальных подходах.
Все сообщения исходящие из браузера перед отправкой проходят процедуру маскировки случайным ключом:
– каждому байту сообщения ставится в соответствие один из четырех байтов маски (по очереди, если байты маски закончились, то байты берутся с начала);
– проводится между байтами маски и сообщения операция XOR (взятие по модулю 2);
– новые байты сообщения записываются как результат данных во фрейм.
Демаскировка производится таким же методом на стороне сервера. Сервер при отправке не маскирует сообщения. При общении двух клиентов сообщения можно и не маскировать, для этого необходимо вручную устанавливать бит маски в 0. Но данную операцию следует проводить только в том случае, если оба клиента доверяют друг другу, так как в противном случае появляется уязвимость в виде атаки «Отравленный кэш» [34].
3.5 Выбор системы управления базами данных
База данных – набор сведений, хранящихся некоторым упорядоченным способом.
Система управления базами данных (СУБД) – это совокупность языковых и программных средств, которая осуществляет доступ к данным, позволяет их создавать, менять и удалять, обеспечивает безопасность данных и прочее. В общем СУБД – это система, позволяющая создавать базы данных и манипулировать сведениями из них [35]. А осуществляет этот доступ к данным СУБД посредством специального языка – SQL.
SQL – язык структурированных запросов, основной задачей которого является предоставление простого способа считывания и записи информации в базу данных [36].
На данный момент широкое распространение получили следующие СУБД:
– MySQL – это самая распространенная полноценная серверная СУБД. MySQL очень функциональная, свободно распространяемая СУБД, которая успешно работает с различными сайтами и веб приложениями. Основной недостаток – необходим сервер MySQL для работы этого типа СУБД [37];
– PostgreSQL является профессиональной СУБД. Она свободно распространяемая и максимально соответствует стандартам SQL. От других СУБД PostgreSQL отличается поддержкой востребованного объектно-ориентированного и/или реляционного подхода к базам данных. Основные недостатки данной СУБД – это медленное чтение при простых операциях и сложная настройка системы [38];
– SQLite – легко встраиваемая в приложения база данных. Так как это система базируется на файлах, то она предоставляет довольно широкий набор инструментов для работы с ней, по сравнению с сетевыми СУБД. При работе с этой СУБД обращения происходят напрямую к файлам (в эти файлах хранятся данные), вместо портов и сокетов в сетевых СУБД. Именно поэтому SQLite очень быстая, а также мощная благодаря технологиям обслуживающих библиотек.
Система управления базами данных SQLite имеет ряд преимуществ:
– файловая структура – вся база данных состоит из одного файла, поэтому её очень легко переносить на разные машины;
– используемые стандарты – несмотря на простоту СУБД, она использует SQL. Некоторые особенности опущенны (RIGHT OUTER JOIN или FOR EACH STATEMENT), но основные все-таки поддерживаются;
– отличная при разработке и тестировании – в процессе разработки приложений часто появляется необходимость масштабирования. SQLite предлагает всё что необходимо для этих целей, так как состоит всего из одного файла и библиотеки написанной на языке C.
Также данная СУБД имеет недостатки:
– отсутствие системы пользователей. Более крупные СУБД включают в свой состав системы управления правами доступа пользователей. Поэтому если необходимо разграничение прав доступа к информации, её необходимо реализовывать в приложении;
– отсутствие возможности увеличения производительности. Все операции в не зависимости от того, сложные они или простые, требуют одно и тоже количество времени навыполнение [39].
Исходя из достоинст и недостатков СУБД SQLite, данная система применяется при:
– разработке встроенных приложений. Отсутствие необходимости в сервере, позволяет легко переносить приложения на различные среды исполнения, что облегчает разработку, например, однопользовательских приложений, мобильных приложения или игр;
– прямом доступ к диску. При необходимости напрямую обращаться к диску появляется выигрыш в функционале и простоте использования SQL языка;
– тестирование. Использование дополнительных процессов при тестировании функционала, очень замедляет приложение. Но так как СУБД их не имеет, то и приложение работает на прежнем уровне.
Поэтому выбор остановился на СУБД SQLite, т.к. имеет соответствующие преимущества для кроссплотформенного приложения онлайн-консультанта, а недостатки данной СУБД не критичны.
4 РЕАЛИЗАЦИЯ ПРИЛОЖЕНИЯ «ОНЛАЙН-КОНСУЛЬТАНТ»
В предыдущей главе выбраны язык программирования, среда разработки, а также способы обмена сервера с различными видами клиентов.
Перейдем к реализации системы «онлайн-консультант», структурная схема взаимодействия которой представлена на рисунке 13.
Рисунок 13 – Реализуемая схема соединения
Данная схема физически упрощена, по сравнению со схемой указанной на рисунке 7. Теперь в роли web-сервера компании разработчика выступает web-сервер предприятия, который помимо этого также является связующим звеном между компьютера сотрудников компании.
4.1 Реализация клиентского приложения
Клиентское приложение построено таким образом, что графическая оболочка программы отделена от её функциональной работы.
Запуск программы начинается с активации её основного класса main(). Данный класс последовательно выполняет следующее:
– поиск файла конфигурации config.cnf и загрузка данных из него, если такие присутствуют и файл существует. В этом файле описаны все основные настройки запуска клиентской части, такие как IP адрес сервера, номер порта и прочее. Код выглядит следующим образом:
readFile = new BufferedReader(new FileReader("config.cnf"));
String s=readFile.readLine();
while(s!=null){
if(s.equals("[Server configer]")){
ip=readFile.readLine().split("=")[1];
port=Integer.parseInt(readFile.readLine().split("=")[1]);
}
s=readFile.readLine();
};
– запуск графического уведомления пользователя о состоянии подключения к серверному приложению с фоновым изображением (рисунок 14), а также различных всплывающих сообщений, уведомляющих об ошибке подключения, выбора адреса сервера и порта;
Рисунок 14 – Фоновое изображение
– подключение к серверу, используя выбранные параметры настройки IP адреса и номера порта;
– запись данных с параметрами настройки подключения в файл config.cnf, при условии, что подключение выполнено успешно;
– запуск окна авторизации пользователя;
– открытие канала получения и канала отправки данных на сервер/с сервера;
– при успешной авторизации – запуск графической оболочки программы, состоящей из главного окна приложения, активной иконки в области уведомлений операционной системы;
– ожидание завершения потоков передачи и получения данных со стороны клиента.
Подробно опишем процесс авторизации пользователя, при подсоединении к серверному приложению. Графический интерфейс пользователя показан на рисунке 15.
Рисунок 15 – Окно авторизации пользователя
После введения данных и нажатия на кнопку «Авторизация» данные имени и пароля отправляются на сервером с кодом «$toServer$ 100», что означает передача серверу данных авторизации. На данный запрос приходит ответное сообщение с сервера об успешности авторизации (код «$accept$») или её ошибке (код «$notaccept$»). Код совершенных команд следующий:
public void sendLogPass(String log, String pass){
out.println("$toServer$ 100"); //Код авторизации
out.println(log);
out.println(pass);
};
while ((input=in.readLine())!=null) {
switch(input){
case "$accept$":{
isAutor=true;
id=Integer.parseInt(in.readLine().split("=")[1]);
this.sleep(2000);
break;
}
case "$notaccept$":
isAutor=false; break;
}
}
Если авторизация прошла успешно, то активируется иконка в системном лотке операционной системы (рисунок 16) и основное окно программы (рисунок 17).
Рисунок 16 – Иконка активного приложения
Диалоги с сотрудниками загружаются в основное окно в виде массива, который заполняется либо при подключении к серверу (при первом подключении происходит загрузка данных с сервера и сохраняется в файл), либо из файла (при повторном запуске программы). Код программы представлен ниже:
try{
IDs=new HashMap<Integer,String>();
readFile = new BufferedReader(new FileReader("temp00"));
String s=readFile.readLine();
while(s!=null){
IDs.put(Integer.parseInt(s.split(":")[0]),
s.split(":")[1]);
if(Integer.parseInt(s.split(":")[0])==get.getID()){
thisID=Integer.parseInt(s.split(":")[0]);
}
s=readFile.readLine();
}
}
catch(IOException ex){
if(ex.getMessage().contains("Не удается найти указанный
файл")){
send.sendSingleRequest("$toServer$ 200");}}
При выборе диалога с сотрудником (рисунок 17), данные переписки между пользователя также загружаются из файла, созданного ранее на компьютере владельца, либо с сервера, если такие данные существуют. Код программы представлен ниже:
try{
readFile = new BufferedReader(new
FileReader("itempd"+thisID));
String s=AES.decrypt(readFile.readLine(),"coding");
String to;
while(s!=null){
if(s.startsWith("[withID=")){
to=s.split("=")[1];
to=to.substring(0, to.length()-1);
LinkedHashMap<String, String> tempHashMap=new
LinkedHashMap<String, String>();
s=AES.decrypt(readFile.readLine(),"coding");
while(!s.contentEquals("[end]") && s!=null){
tempHashMap.put(s.split(":", 2)[0], s.split(":", 2)[1]);
s=AES.decrypt(readFile.readLine(),"coding");
}
talks.put(Integer.parseInt(to), tempHashMap);