Тема: Разработка приложения для автоматического обеспечения передачи оповещения с мобильного телефона на компьютер

  • Вид работы:
    Диплом
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
  • Формат файла:
    MS Word
  • Размер файла:
    339,77 Кб
Разработка приложения для автоматического обеспечения передачи оповещения с мобильного телефона на компьютер
Разработка приложения для автоматического обеспечения передачи оповещения с мобильного телефона на компьютер
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

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

Федеральное государственное автономное образовательное учреждение

высшего образования

"БАЛТИЙСКИЙ ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ

ИМЕНИ ИММАНУИЛА КАНТА"

Институт транспорта и технического сервиса





Дипломная работа

Разработка приложения для автоматического обеспечения передачи оповещения с мобильного телефона на компьютер



Разработал студент

Шелыгин Д.С.

дневной формы обучения

Специальность "Программирование в компьютерных системах"

Научный руководитель

Румянцева Е.В.



Калининград 2016

Содержание

Введение

1. Назначение и область применения

2. Описание и обоснование

2.1 Обзор мобильной операционной системы Android

2.1.1 Архитектура ОС Android

2.1.2 Уровень приложений

2.1.3 Уровень каркаса приложений

2.1.4 Уровень библиотек

2.1.5 Уровень среды исполнения

2.1.6 Уровень ядра Linux

2.2 Описание разработанной системы

2.2.1 Структура системы

2.2.3 Назначение и принцип работы Android-приложения

2.2.3 Назначение и принцип работы ПК-клиента

2.2.4 Назначение и принцип работы сервера

2.3 Безопасность разработанной системы

3. Результаты тестирования

4. Экономическое обоснование дипломного проекта

4.1 Расчет себестоимости создания системы

4.2 Расчет срока окупаемости системы

4.3 Анализ действующих цен на рынке

5. Охрана окружающей среды и техника безопасности

Заключение

Список используемых источников

Введение

С каждым днем персональный компьютер все больше и больше вытесняется смартфонами. Уже с уверенностью можно сказать, что настала эра мобильных телефонов. Большинство приложении ежедневно портируются на Android и iOS. Мобильные технологии развиваются с невероятной скоростью. Изо дня в день телефоны становятся все мощнее и функциональнее. Скоро их возможности совсем не будут уступать возможностям персонального компьютера. Человек нуждается в мобильных приложениях в частности из-за того, что свой смартфон он может использовать где угодно и когда угодно, в отличии от персонального компьютера. К тому же мобильный интернет есть уже абсолютно в любом населенном пункте.

Однако персональные компьютеры все еще существуют в каждом доме и люди по-прежнему их используют. Для работы, для учебы, поиграть в игры, посмотреть фильм. В настоящее время компьютер и телефон синхронизируют большую часть данных. Будь то фотографии, музыка или документы. Но что, если телефон пришло уведомление о новом сообщении, но сам телефон находится в соседней комнате. Хотелось бы, находясь перед экраном монитора, знать об этом уведомлении.

Задачей для данной дипломной работы является разработка системы синхронизации уведомлений. Приложение под Android, клиент для Windows и сервер. Используемые языки программирование: Java и C#.

Цель дипломной работы:

.Разработать клиентское приложение для смартфонов под управлением операционной системы Android версии 4.0.0 и выше. Оно должно отправлять серверу информацию получении нового уведомления.

2.Разработать клиентское приложение для персональных компьютеров с операционной системой Windows с.net Framework версии 4 и выше. Клиент должен получать от сервера данные, отправленные ему с Android-устройства и выводить сообщение и этими данными на экран компьютера.

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

Решаемые задачи:

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

2.Ознакомиться с многопоточными приложениями и особенностями платформы Android.

.Закрепить знания разработки клиент-серверных приложений на языке C#.

.Научиться разрабатывать асинхронные серверные приложения.

1. Назначение и область применения

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

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

синхронизация уведомление приложение сервер

2. Описание и обоснование

2.1 Обзор мобильной операционной системы Android

ОС Android - операционная система для мобильных телефонов, планшетных компьютеров и нетбуков, которая основывается на ядре Linux. Изначально ОС Android разрабатывала компания Android Inc., но затем ее купила компания Google. Впоследствии, компания Google инициировала создание альянса компаний Open Handset Alliance (OHA), занимающегося поддержкой и дальнейшим развитием платформы. Первая версия ОС Google Android вышла в сентябре 2008 года. В конце 2010 года ОС Android стала самой продаваемой ОС для смартфонов.

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

Для разработки приложений под платформу Android используется набор инструментов и библиотек API - Android SDK, предназначенный для компьютеров с архитектурой процессора x86 под операционными системами Windows, Mac OS X и Linux. Для разработки требуется среда исполнения Java Runtime Environment (JRE), комплект разработчика Java Development Kit (JDK), среда разработки Android Studio и Android SDK. Разработку приложений для ОС Android можно вести на языке Java. Кроме того, существуют плагины, облегчающие разработку Android-приложений в средах разработки IntelliJ IDEA и NetBeans IDE. MonoDroid SDK позволяет писать для ОС Android на C# и других языках.

2.1.1 Архитектура ОС Android

На Рисунке 1 представлена диаграмма основных компонентов операционной системы Android.

Рисунок 1. Основные компоненты ОС Android

2.1.2 Уровень приложений

Операционная система Android имеет базовый комплект приложений таких как приложение для электронной почты, календарь, карты, вэб-браузер и многое другое. Все приложения, запускаемые на платформе Android, написаны на языке Java.

2.1.3 Уровень каркаса приложений

ОС Android позволяет полностью использовать API, применяемый в приложениях ядра. Архитектура построена так, что каждое приложение способно использовать возможности и ресурсы иного приложения при том условии, что это приложение разрешит доступ на использование своих функций. Благодаря этому, архитектура операционной системы Android реализует принцип неоднократного использования компонентов приложений и самой ОС.

Системы и службы являются основой всех приложений:

. Менеджер действий (Activity Manager) позволяет управлять жизненным циклом приложения, предоставлять ему систему навигации по истории работы с действиями.

. Контент-Провайдеры (Content Providers) представляют собой сервисы, позволяющие различным приложениям иметь доступ к данным иных приложений, и, если необходимо, предоставлять им доступ к своим данным.

. Система представлений (View System) является набором представлений, имеющих расширяемую функциональность. Она необходима при создании внешнего вида приложений. Включает в себя различные компоненты, например, кнопки, поля ввода текста, выпадающие списки и многое другое.

. Менеджер ресурсов (Resource Manager) предназначается для получения доступа к графическим, строковым и прочим видам ресурсов.

. Менеджер извещений (Notification Manager) - это менеджер, позволяющий каждому приложению отображать пользовательские уведомления в строке статуса.

2.1.4 Уровень библиотек

Платформа Android имеет несколько C/C++ библиотек, которые используются разными компонентами операционной системы. Application Framework предоставляет разработчикам доступ к функциям этих библиотек. Примеры библиотек:

. System C library - реализация базовой системной библиотеки C (libc) для встраиваемых устройств, на ядре Linux.

. Media Libraries - библиотеки, предназначающиеся для поддержки воспроизведения и записи большинства популярных аудио-форматов и видео-форматов, таких как MP3, MPEG4, AAC, JPG, PNG и прочих. Они основаны на технологии PacketVideos OpenCORE.

. LibWebCore - ядро встроенного web-браузера.

. Surface Manager (менеджер поверхностей) - библиотека, предоставляющая доступ к подсистеме отображения 2D - и 3D - графических слоев.

. SGL (Scalable Graphics Library) - библиотека для работы с 2D-графикой, основанная на библиотеке SDL (Simple DirectMedia Layer).

.3D libraries - библиотеки для работы с 3D-графикой, основанные на OpenGL ES 1.0 API.

. FreeType - библиотека, необходимая для работы со шрифтами.

. SQLite - легковесная реляционная система управления базами данных.

2.1.5 Уровень среды исполнения

В состав ОС Android входит набор библиотек ядра, которые предоставляют большую часть функциональности библиотек ядра языка Java.

Платформа использует виртуальную машину Dalvik. Это оптимизированная, регистр-ориентированная виртуальная машина. В отличии от нее, стандартная виртуальная машина Java является стек-ориентированной. Любое приложение работает в рамках своего собственного процесса и со своим собственным экземпляром виртуальной машины. Виртуальная машина Dalvik использует формат Dalvik Executable (*. dex). Этот формат оптимизирован для использования приложением минимального объема памяти. Это происходит благодаря такими базовыми функциями ядра Linux, как организация поточной обработки и низкоуровневое управление памятью. Специальная утилита dx, входящая в состав SDK компилирует байт-код Java, на котором написаны приложения, в dex-формат.

2.1.6 Уровень ядра Linux

ОС Android основана на ядре Linux версии 2.6 Благодаря этому платформа имеет доступ к системным службам ядра, таким как управление памятью и процессами, обеспечение безопасности, работа с сетью и драйверами. Также ядро служит слоем абстракции между аппаратным и программным обеспечением.

2.2 Описание разработанной системы

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

2.2.1 Структура системы

Система состоит из приложения для Android, клиентского приложения для Windows и сервера.

Рисунок 2. Структура системы синхронизации уведомлений

2.2.3 Назначение и принцип работы Android-приложения

В операционной системе Android присутствуют push-уведомления, которые сообщают пользователю о каком-либо событии (пропущенный вызов, новое сообщение, низкий уровень заряда батареи). Так как целью дипломной работы является синхронизация этих уведомлений с персональным компьютером, то данное приложение должно отправлять информацию, извлеченную из новых уведомлений клиенту на персональном компьютере, через сервер. Для того, чтобы сервер знал, какому клиенту перенаправить принятые данные, пользователю необходимо ввести имя (соответствующее имени ПК-клиента). Для того, чтобы приложение функционировало в фоновом режиме, необходимо создать на устройстве сервис.

Сервисы (службы) в Android работают как фоновые процессы и представлены классом android. app. Service. Они не имеют пользовательского интерфейса и нужны в тех случаях, когда не требуется вмешательства пользователя. Сервисы работают в фоновом режиме, выполняя сетевые запросы к веб-серверу, обрабатывая информацию, запуская уведомления и т.д. Сервис может быть запущен и будет продолжать работать до тех пор, пока кто-нибудь не остановит его или пока он не остановит себя сам. Сервисы предназначены для длительного существования, в отличие от активностей (activity). Они могут работать, постоянно перезапускаясь, выполняя постоянные задачи или выполняя задачи, требующие много времени.

При первом запуске приложения, пользователь сталкивается с формой, которая имеет два поля для ввода и одну кнопку. Первое поле предназначено для ввода ip-адреса сервера, которому приложение затем будет отправлять информацию. Второе поле предназначено для ввода имени пользователя (никнейма). Оно необходимо для того, чтобы сервер мог идентифицировать подключенные к нему устройства и ПК-клиенты. Имя обязательно должно совпадать с тем, которое введено (или будет введено) при подключении с ПК-клиента. Кнопка изначально является неактивной. Это сделано для того, чтобы пользователь случайно не нажал на нее, не введя ip-адрес, из-за чего произошла бы ошибка.

Рисунок 3. Стартовый экран Android-приложения

После того, как оба поля заполнены, кнопка становится активной, и пользователь может на нее нажать. После нажатия на кнопку, происходит подключение к серверу с заданным ip-адресом и портом 31111, и на устройстве создается новый сервис, который называется Notification Catch Service. Сервис необходимо вручную включить в меню настроек телефона во вкладке "Специальные возможности" ("Accessibility).

Рисунок 4. Notification catch service во вкладке специальных возможностей.

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

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

Для того, что соединение не обрывалось при отключении сервиса, класс, создающий соединение, ServerConnection, расширяет класс AsyncTask.- это абстрактный класс, позволяющий правильно и легко использовать главный поток приложения, обслуживающий интерфейс пользователя (UI thread). Этот класс позволяет выполнять длительные операции в отдельном потоке и отображать их результаты в UI thread, без всякой необходимости вручную манипулировать потоками thread или обработчиками (handler).разработан, чтобы быть классом-оберткой (helper class) вокруг классов Thread и Handler, и он не составляет универсальную платформу для поточной обработки. AsyncTasks идеально подходит не только для коротких операций (занимающих по времени около нескольких секунд), но и для операций, выполняемых в бесконечном цикле.

Как понятно уже из названия, класс AsyncTask предназначен для выполнения асинхронных по отношению к UI thread задач. Асинхронная задача - это некое вычисление, которое работает в фоновом потоке, и свои результаты публикует в UI thread. Асинхронная задача определена 3 стандартными типами, которые называются Params, Progress и Result, и 4 методами, называемыми onPreExecute, doInBackground, onProgressUpdate и onPostExecute. Для начала работы объекта этого класса, используется метод Execute.

Метод onPreExecute выполняется один раз - сразу после того, как выполнится метод Execute. Это, своего рода, конструктор класса. Обычно его используют для инициализации объектов класса.

Метод doInBackground является основным методом, который будет выполнять описанные в нем операции в фоновом режиме.- это метод, в котором будут выполняться промежуточные операции. Он принимает аргументы такого типа, который указан вторым при объявлении типов параметров класса AsyncTask.

Метод onPostExecute - это своеобразный деструктор класса. Он выполниться один раз по завершении работы метода doInBackground. Как и в деструкторах, в этом методе обычно уничтожают динамические объекты или разного рода соединения.

В данном приложении использовались лишь три метода - onPreExecute, doInBackground и onPostExecute, потому как никаких промежуточных операций выполнять не требуется. В методе onPreExecute инициализируются объекты классов Socket и PrintWriter. В методе doInBackground серверу отправляется сообщение следующего типа: "@@onConnection# + имя пользователя". Затем соединение простаивает для того, чтобы в дальнейшем с его помощью отправлять серверу сообщения. В методе onPreExecute это соединение уничтожается.

@Override

protected Void doInBackground (Void. params) {

try {("@@onConnection#" + MainActivity. getName ());

}

catch (IOException ex) {. printStackTrace ();

}

return null;

}

@Override

protected Void onPreExecute (Void. params) {

try{= new Socket (SERVER_IP, SERVER_PORT);= new PrintWriter (socket. getOutputStream (), true);

}

catch (IOException ex) {. printStackTrace ();

}

return null;

}

@Override

protected Void onPostExecute (Void. params) {

try{. close ();. flush ();. close ();

}

catch (Exception ex) {. printStackTrace ();

}

}

Рисунок 4. Исходный код класса ServerConnection

В данном случае класс AsyncTask не принимает никаких параметров, то есть все три параметра равны Void.

public class ServerConnection extends AsyncTask<Void, Void, Void>

Рисунок 5. Объявление класса ServerConnection

Также, класс ServerConnection имеет метод sendMessage, принимающий аргумент типа String и не возвращающий ничего. Этот метод, при помощи ранее инициализированного объекта класса PrintWriter, отправляет серверу сообщение, которым и является передаваемый аргумент.

void sendMessage (String msg) {

try {. print (msg);. flush ();

} catch (Exception ioException) {. printStackTrace ();

}

}

Рисунок 6. Метод sendMessage

Самым главным классом в любом Android-приложении является класс MainActivity. С его метода onCreate запускается приложение. В данном приложении в методе onCreate объявляется слушатель (Listener) нажатия на кнопку "GO!".- это специальный механизм в языке Java (и не только в нем), который реагирует на какое-либо событие (Event), будь то нажатие кнопки, движение мышью, касание экрана и т.д.

Обработка большинства событий, таких как, например, нажатие на кнопку, клик мышью и прочих, происходит посредством связывания этого события с каким-либо методом, который будет его обрабатывать. Начиная с Java версии 2, обработка событий основывается на модели делегирования событий. Эта модель состоит из блока прослушивания события (EventListener), ожидающего поступления определенного события от источника, за которым следует его обработка и возвращается управление. Источником называют объект, генерирующий событие, при изменении его внутреннего состояния. Например, если изменился размер какого-либо элемента, изменилось значение некоего поля, был клик кнопки мыши на элементе формы или выбрано какое-либо значение из выпадающего списка. После генерации объект-событие передается для обработки зарегистрированному в источнике блоку прослушивания как параметр его методов - обработчиков событий. Объекты классов, которые реализуют интерфейсы прослушивания событий, определенных в пакете java. awt. event, представляют собой блоки прослушивания слушателя. При создании собственных классов прослушивания, соответствующие методы, которые были объявлены в используемых интерфейсах, требуется явно реализовать. Эти методы и будут являться обработчиками события. Объект-событие, который передается источником блоку прослушивания является аргументом обработчика события. Объект класса - блока прослушивания события необходимо зарегистрировать в источнике методом addListener. После чего объект-слушатель начнет реагировать именно на данное событие и вызывать указанный метод-обработчик события. Такая логика обработки событий предоставляет легкое отделение интерфейсной части приложения от его функциональной части, что считается необходимым при проектировании современных приложений.

@Override

protected void onCreate (Bundle savedInstanceState) {

super. onCreate (savedInstanceState);(R. layout. activity_main);

final Button button = (Button) findViewById (R. id. okButton);

final EditText editText = (EditText) findViewById (R. id. editText);

final EditText ipEditText = (EditText) findViewById (R. id. ipEditText);. setOnClickListener (new View. OnClickListener () {

@Override

public void onClick (View view) {= editText. getText (). toString ();= ipEditText. getText (). toString ();. setVisibility (View. INVISIBLE);. setVisibility (View. INVISIBLE);();

}

});. setOnTouchListener (new View. OnTouchListener () {

@Override

public boolean onTouch (View v, MotionEvent event) {. setEnabled (true);

return false;

}

});fab = (FloatingActionButton) findViewById (R. id. fab);. setOnClickListener (new View. OnClickListener () {

@Override

public void onClick (View view) {context = getApplicationContext ();notificationIntent = new Intent (context, MainActivity. class);contentIntent = PendingIntent. getActivity (context,

, notificationIntent,. FLAG_CANCEL_CURRENT);. Builder builder = new Notification. Builder (context);. setContentIntent (contentIntent)

. setSmallIcon (R. mipmap. ic_launcher)

. setTicker ("Test notification")

. setWhen (System. currentTimeMillis ())

. setAutoCancel (true)

. setContentTitle ("Напоминание")

. setContentText ("notification");notification = builder. build ();nm = (NotificationManager) context

. getSystemService (Context. NOTIFICATION_SERVICE);. notify (NOTIFY_ID, notification);

}

});

}

Рисунок 7. Метод onCreate

Помимо метода onCreate, в классе MainActivity описаны еще несколько классов. Автоматически созданные средой разработки методы onCreateOptionMenu и OnOptionItemSelected. Эти методы необходимы для реализации меню в приложении. А также методы getName, getIP и goService.

static String getName () { return name; }

public static String getIP () { return ip; }

private void goService () {intent = new Intent (MainActivity. this, NotificationWorker. class);(intent);

}

@Override

public boolean onCreateOptionsMenu (Menu menu) {(). inflate (R. menu. menu_main, menu);

return true;

}

@Override

public boolean onOptionsItemSelected (MenuItem item) {id = item. getItemId ();

if (id == R. id. action_settings) {

return true;

}

return super. onOptionsItemSelected (item);

}

Рисунок 8. Методы класса MainActivity

Метод getName является, так называемым, геттером, статическим методом, позволяющим безопасно получить значение какого-либо объекта или переменной. Данный метод возвращает значение, введенное пользователем в поле "Имя". Метод getIP - еще один геттер, возвращающий введенный пользователем IP-адрес. goService является методом, который создает вышеупомянутый сервис на устройстве. В этом методе инициализируется объект класса Intent, в конструктор которого передается ссылка на класс NotificationWorker. Затем вызывается метод startService, аргументом которого передается вышеупомянутый объект класса Intent. Intent (от англ. Намерение) - это механизм, описывающий какую-то операцию. Например, выбор фотографии, отправка письма, совершение звонка, запуск браузера или открытие страницы по указанному вэб-адресу. В Android-приложениях через намерения работает большое количество операций.

Наиболее распространенный пример использования намерения - это запуск другой активности (Activity) в своём приложении. Также можно использовать для объявления о запуске активности или сервиса, направленных на выполнение каких-либо действий (как правило, речь о работе с определенной частью данных) или для передачи уведомлений о том, что произошло некое событие (или действие).

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

Класс NotificationWorker - это класс, наследуемый от класса AccessibilityService, и предназначенный для описания работы сервиса.

В конструкторе класса NotificationWorker инициализируется объект класса serverConnection и выполняется его метод execute.

NotificationWorker () {= new ServerConnection ();. execute ();

}

Рисунок 9. Конструктор класса NotificationWorker

Далее, переопределены три метода класса AccessibilityService:(AccessibilityEvent event) - это метод, который будет выполняться, когда на устройстве обнаружится новое уведомление. Объект event хранит в себе большое количество различной информации о произошедшем событии. В данном методе создается локальная переменная типа String (строка) и присваивается значение следующего вида - "name#packageName: text", где name - это имя пользователя, указанное при первом запуске приложения, знак # - это separator (разделитель), он предназначен для того, чтобы сервер отделил имя клиента от сообщения, packageName - это название пакета приложения, создавшего уведомление, text - это текст сообщения в уведомлении. Далее, метод encode зашифровывает текст для безопасности. Затем вызывается метод класса serverConnection sendMessage, в который передается вся вышеуказанная, уже зашифрованная, строка.

@Override

public void onAccessibilityEvent (AccessibilityEvent event) {

if (event. getEventType () == AccessibilityEvent. TYPE_NOTIFICATION_STATE_CHANGED) {

String packageName = String. valueOf (event. getPackageName ());

String text = event. getText (). toString ();

String toSend = name + "#" + packageName + ": " + text;. i ("notifyService", toSend);= encode (toSend);. sendMessage (toSend);

}

}

Рисунок 10. Метод onAccessibilityEvent

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

@Override

public void onInterrupt () {

}

Рисунок 11. Метод onIterrupt

- это метод, который выполняется при запуске сервиса. Здесь описывается на какой вид события должен реагировать сервис. Сделано это при помощи класса AccessibilityServiceInfo, свойству eventType которого присвоено константное значение enum-класса (перечисление) AccessibilityEvent TYPE_NOTIFICATION_STATE_CHANGED.

@Override

protected void onServiceConnected () {. i ("notifyService", "onServiceConnected ");info = new AccessibilityServiceInfo ();. eventTypes = AccessibilityEvent. TYPE_NOTIFICATION_STATE_CHANGED;. notificationTimeout = 100;. feedbackType = AccessibilityEvent. TYPES_ALL_MASK;(info);

}

Рисунок 12. Метод onServiceConnected

2.2.3 Назначение и принцип работы ПК-клиента

Клиент для ПК работает под управлением операционной системы Windows. Он соединяется с тем же сервером, с которым соединено Android-устройство пользователя. Клиент в отдельном потоке начинает прослушивать сокет и, получив данные от сервера, отображает их на экране. Клиент разрабатывался с помощью технологии WPF (Windows Presentation Foundation). WPF является системой построения клиентских приложений для операционной системы Windows с визуально привлекательными возможностями взаимодействия с пользователем. Она входит в состав.net Framework с версии 3.0. Для построения графического интерфейса пользователя в WPF используется язык XAML.(eXtensible Application Markup Language) является декларативным языком разметки, упрощающим создание графического интерфейса пользователя для приложения на.net Framework. XAML позволяет сначала создавать видимые элементы графического интерфейса в декларативной разметке XAML, а после чего отделять его от логики времени выполнения, при помощи использования файлов кода программной части, присоединенных к разметке XAML при помощи определений разделяемых классов. Этот язык разметки представляет создание экземпляров объектов напрямую, в определенном наборе резервных типов, которые определенны в сборках. В этом и есть его отличие от остальных языков разметки, являющихся интерпретируемыми языками, которые не имеют прямой связи с системой резервных типов. Язык XAML позволяет обеспечивать рабочий процесс нескольким участникам, разрабатывающим пользовательский интерфейс и логику приложения отдельно, используя потенциально различные средства.

При запуске приложение, пользователю необходимо ввести имя и IP-адрес сервера, и нажать кнопку "ОК". После чего создается экземпляр класса TcpClient и выполняется его метод Connect, в который передается введенный IP-адрес и порт 31111. Для того, чтобы работа GUI (graphical user interface) не мешал соединению, т.е. не прерывал его при отображении полученного сообщения от сервера, соединение создается в отдельном потоке и продолжает свою работу до тех пор, пока приложение полностью не закроется.

Рисунок 13. Стартовый экран ПК-клиента.

Данное приложение состоит из двух классов - MainWindow и Connection.

Класс Connection - это класс, который создается соединение с сервером и позволяет в отдельном потоке прослушивать это соединение. Он содержит в себе вложенный класс (inner class) State, который предназначен для хранения информации о соединении. Класс State содержит в себе три поля (field) - buffer, socket и msg. Поле buffer - это массив типа byte []. Он необходим для временного хранения информации, полученной с сервера, так как информация передается в виде массива байт. Поле socket - это объект класса Socket, предназначенное для хранения соединения. Поле msg - это переменная типа string. Оно требуется для хранения в себе сообщения, полученного из массива байт buffer.

class State

{

public State (byte [] buffer, Socket socket, string msg)

{

this. buffer = buffer;

this. socket = socket;

this. msg = msg;

}

public byte [] buffer;

public Socket socket;

public string msg;

}

Рисунок 14. Внутренний класс State

Конструктор класса Connection принимает три аргумента:

-string name - строковое значение имени пользователя

-string ip - строковое значение ip-адреса сервера, к которому необходимо подключиться.

-int port - значение типа Integer, обозначающее порт.

В конструкторе класса Connection создается объект класса TcpClient. TcpClient - это класс, предоставляющий простейшие методы для создания соединения, отправления и приема различной информации через протокол tcp. Затем создается объект класса IPEndPoint, в конструктор которого передаются ip-адрес и порт. После чего выполняется метод Connect, в который передается объект класса IPEndPoint. Далее объявляется поле ns типа NetworkStream, которому присваивается поток соединения объекта client при помощи метода GetStream. Затем серверу отправляется сообщение следующего типа: "@@onConnection#name-pc", где @@onConnection - это флаг, обозначающий, что это сообщение предназначено только для занесения имени клиента в пул подключений сервера, а не переотправки его другому клиенту, знак # - это сепаратор, отделяющий флаг от имени, name является именем пользователя, которое он ввел в соответствующее поле на форме, постфикс "-pc" необходим для того, что сервер в дальнейшем отличал какое соединение от смартфона, а какое от персонального компьютера, так как имена обязательно должны вводиться одинаковые. После отправки сообщения, вызывается метод StartReceiving, в который передается объект client.

Connection (string name, string ip, int port)

{= new TcpClient ();point = new IPEndPoint (IPAddress. Parse (ip), port);. Connect (point);ns = client. GetStream ();

byte [] buffer = Encoding. ASCII. GetBytes ("@@onConnection#" + name + "-pc");. Write (buffer, 0, buffer. Length);

// ns. Close ();(client);

}

Рисунок 15. Конструктор класса Connection

Метод StartReceiving - это метод, в котором клиент начинает прослушивать сервер через указанные ip-адрес и порт. В этом методе создаются три локальные переменные - buffer размером 1024 байта, пустое строковое поле message и socket, которому приравнивается свойство Client объекта client. Затем создается экземпляр внутреннего класса State, который принимает buffer, socket и message. После этого у объекта socket вызывается метод BeginReceive, который начинает асинхронный прием данных с подключенного объекта Socket. Метод BeginReceive имеет множество перегрузок, одна из которых принимает следующие аргументы:

-Buffer - массив типа Byte, который является местоположением памяти для полученных данных.

-Offset - отсчитываемая с нуля позиция в параметре buffer, начиная с которой хранятся принятые данные.

-Size - число принимаемых байтов.

-socketFlags - поразрядное сочетание значений SocketFlags.

-Callback - делегат AsyncCallback, ссылающийся на метод, вызываемый по завершении данной операции.

-State - пользовательский объект, содержащий информацию об операции приема. Этот объект передается делегату EndReceive по завершении операции.

. BeginReceive (state. buffer, 0, state. buffer. Length, SocketFlags. None, new AsyncCallback (ReceiveCallback), state);

Рисунок 16. Вызов метода BeginReceive

Затем полю message приравнивается значение, полученное из массива байт buffer.

void StartReceiving (TcpClient client)

{

byte [] buffer = new byte [1024];

string message = String. Empty;socket = client. Client;

// while (true)

// {state = new State (buffer, socket, message);. BeginReceive (state. buffer, 0, state. buffer. Length, SocketFlags. None, new AsyncCallback (ReceiveCallback), state);= Encoding. ASCII. GetString (buffer);

// }

}

Рисунок 17. Метод StartReceiving

- это метод, на который ссылается делегат AsyncCallback в методе BeginReceive. ReceiveCallback вызывается после получения от сервера каких-либо данных. В этом методе создается локальный экземпляр класса State, которому присваивается значение свойства AsyncState объекта IAsyncResult, который передается аргументом в ReceiveCallback. Так как AsyncState является свойством типа object, а не State, то необходимо использовать кастинг (casting). Кастинг - это явное преобразование объекта одного типа к другому типу.

Затем создается локальный объект класса Socket, которому присваивается поле socket объекта state, тем самым позволяя в этом методе работать все с тем же подключением.

После этого вызывается метод объекта socket EndRecieve, возвращающий значение типа int. Это значение присваивается локальной переменной bytesRead. Если от сервера получены хоть какие-то данные, то bytesRead будет иметь значение больше нуля.

За счет этого происходит проверка, получены ли какие-нибудь данные. Если получены, тогда массив преобразовывается в строку и создается MessageBox, отображающий эти данные. MessageBox - это класс, создающий диалоговое окно, отображающее текст с информацией. MessageBox может содердать текст, кнопки, символы, с помощью которых информируется и инструктируется пользователь. Класс MessageBox входит пространство имен System. Windows. Forms.

void ReceiveCallback (IAsyncResult ar)

{

try

{state = (State) ar. AsyncState;socket = state. socket;

int bytesRead = socket. EndReceive (ar);

if (bytesRead > 0)

{

string msg = Encoding. ASCII. GetString (state. buffer, 0, bytesRead);. Show (msg);

}

}

catch (Exception e)

{. Show (e. ToString ());

}

}

Рисунок 18. Метод ReceiveCallback

Класс MainWindow - это класс для работы с главной формой. Он предназначен для описания только логики работы интерфейса пользователя. Сам интерфейс описывается в отдельном файле MainWindow. xaml.

<Window x: Class="Notiful_Client. MainWindow"="#"justify"><Grid>

<Label Content="Введите имя" Margin="10,54,10,232"/>

<TextBox Name="nameTextBox" Margin="10,94,10, 196"/>

<Button Margin="27,257,237,34" Click="Button_Click" Content="OK"/>

<Label x: Name="label" Content="Введите IP" HorizontalAlignment="Left" Margin="10,130,0,0" VerticalAlignment="Top"/>

<TextBox x: Name="ipTextBox" Margin="10,156,10,137"/>

</Grid>

</Window>

Рисунок 19. XAML-разметка ПК приложения

Класс MainWindow описан в файле MainWindow. xaml. cs. Этот класс содержит только один метод и конструктор.

В конструкторе класса вызывается статический метод InitializeComponent, который необходим для отрисовки интерфейса пользователя (GUI), описанного в MainWindow. xaml.

Метод Button_Click - это метод, который вызывается при нажатии на кнопку на интерфейсе пользователя.

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

<Button Margin="27,257,237,34" Click="Button_Click" Content="OK"/>

Рисунок 20. XAML-разметка кнопки

В этом методе строковым переменным name и ip приравниваются значения, введенные пользователем в соответствующий поля на форме. Затем инициализируется объект класса Connection, в конструктор которого передаются переменные name и ip, а также целочисленное значение 31111, означающее порт.

2.2.4 Назначение и принцип работы сервера

Сервер, также, как и ПК-клиент, запускается под управлением операционной системы Windows. На сервере реализованы асинхронные TCP-соединения. TCP (transmission control protocol) - один из основных протоколов передачи данных через интернет. Предназначается для управления передачей данных. Сети и подсети, в которых совместно используются протоколы TCP и IP называются сетями TCP/IP. В стеке протоколов TCP/IP протокол TCP работает на таком же уровне, что и протокол UDP, на транспортном. Он позволяет, методом установки логического соединения, обеспечивать надежную транспортировку данных между несколькими прикладными процессами. В протоколе TCP для связи с необходимыми прикладными процессами используются порты. Номера портов присваиваются произвольно. Однако имеются зарезервированные номера портов (например, номер 21-сервис FTP, 80 - http). В протоколе TCP порты используются немного другим способом, нежели в UDP. Для того, чтобы организовать надежную передачу данных, устанавливается логическое соединение между двумя прикладными процессами. В пределах этого соединения происходит подтверждение корректности приема для всех переданных сообщений, и при необходимости выполняется повторная передача. С TCP-соединением можно вести одновременную передачу данных в обе стороны. Это называется полнодуплексной передачей.

Идентифицируется соединения в протоколе TCP осуществляется парой полных адресов обоих взаимодействующих процессов, также называемых оконечными точками. Адрес каждой оконечной точки включает в себя: IP-адрес и номер порта. Одна оконечная точка может участвовать сразу в нескольких соединениях.

Сервер не имеет GUI (графического интерфейса пользователя). Он представляет собой обыкновенную консоль от Microsoft. Это сделано потому, что нет необходимости иметь быстрый доступ к каким-либо компонентам, соответственно не нужны никакие кнопки, меню и прочее. К тому же на систему приходится меньшая нагрузка.

Рисунок 21. Внешний вид серверного приложения

На сервере используется асинхронная архитектура выполнения задач, а не многопоточная. Разница между этими архитектурами заключается в следующем:

Многопоточная архитектура

Данная архитектура работает по принципу, при котором приложение создает пул потоков и каждому из них передает задачу с данными для обработки. Все эти задачи выполняются параллельно друг другу. Накладных расходов на синхронизацию не происходит при условии, что потоки не имеют общих данных. Это делает работу достаточно быстрой. Завершив работу, поток остается в пуле и ожидает следующей задачи, а не уничтожается, что позволяет убрать накладные расходы на создание и удаление потоков. Один поток обрабатывает только одну задачу. Пул может иметь огромное количество потоков. Медленные задачи занимают поток надолго, быстрые - обрабатываются почти мгновенно и освобождают поток для другой работы. Это позволяет медленным задачам не забирать всё процессорное время и заставлять подвисать быстрые задачи. Однако у такой системы есть определенные ограничения. Если программе потребуется обработать большое количество медленных задач, например, работающих с базой данных или с файловой системой, эти задачи займут все потоки и сделают невозможным выполнение других задач. Даже если задаче требуется 1мс чтобы выполниться, вовремя выполнена она все равно не будет. Есть вариант решения этой проблемы путем увеличения числа потоков, с целью обработки ими большего количество медленных задач. Однако, выделяет процессорное время и обрабатывает потоки операционная система. Именно поэтому с увеличением потоков увеличиваются накладные расходы на их обработку и уменьшается процессорное временя, которое выделяется каждому потоку. Блокирующие операции работы с базами данных, с файловой системой, вводом/выводом данных тоже тратят огромное количество процессорного времени, при этом не выполняя никакой полезной работы.

Асинхронная архитектура

Асинхронная архитектура основывается на механизме очереди событий (event-loop). Когда возникает некоторое событие, оно помещается в конец очереди. Эту очередь обрабатывает отдельный поток. Он берет событие с начала очереди и выполняет связанный с этим событием код. Пока очередь не пуста, процессор занят работой. Например, имеется единственный поток, обрабатывающий очередь событий. Почти все операции неблокирующие. Блокирующие тоже имеются, но их использование крайне не рекомендуется. Из очереди сообщений берется событие, связанное с приходом запроса. Обработка запроса тратит 1мс. Далее делается асинхронный неблокирующий запрос к базе данных и управление сразу же передается дальше. Можно взять из очереди следующее событие и выполнить его. Например, еще один запрос, проводится обработка, посылается запрос к БД, возвращается управление и проделывается то же самое еще один раз. И тут приходит ответ БД на самый первый запрос. Событие, связанное с ним, помещается в очередь. Если в очереди ничего не было - он сразу же выполнится, данные обрабатываются и отправляются клиенту. Если в очереди что-то есть - придется подождать обработку других событий. Обычно скорость обработки одного запроса будет сравнима со скоростью обработки многопоточной системой и блокирующими операциями. В худшем случае - на ожидание обработки других событий потратится время, и запрос обработается медленнее. Но зато в тот момент, пока система с блокирующими операциями просто ждала бы 2 мс ответа, система с неблокирующими операциями успела выполнить еще 2 части двух других запросов. Каждая задача может выполняться чуточку медленнее в целом, но в единицу времени мы можем обработать гораздо больше задач. Общая производительность будет выше. Процессор всегда будет занят полезной работой. При этом на обработку очереди и переходе от события к событию тратится гораздо меньше времени, чем на переключение между потоками в многопоточной системе. Многопоточная система с блокирующими операциями имеет большое время простоя. Чрезмерное количество потоков может создать много накладных расходов, недостаточное же количество может привести к замедлению работы при большом количестве медленных запросов. Асинхронное приложение с неблокирующими операциями использует процессорное время эффективнее, но более сложно при проектировании.

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

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

-workSocket - это экземпляр класса Socket

-BufferSize - переменная типа int, обозначающая размер массива buffer

-buffer - массив типа byte [], необходимый для хранения данных в виде байт

-sb - экземпляр класса StringBuilder, предоставляющий многофункциональную работу на строками

-name - строковое значение, обозначающее имя соединения

class StateObject

{

public Socket workSocket = null;

public const int BufferSize = 1024;

public byte [] buffer = new byte [BufferSize];

public StringBuilder sb = new StringBuilder ();

public string name = "";

}

Рисунок 22. Внутренний класс StateObject

- это второй вложенный класс, представляющий собой всю логику работы сервера. Этот класс содержит несколько методов, а также метод Main, с которого начинается любая программа.

Метод StartListening - это метод, открывающий сокет, через который будут поступать новые подключения.

В этом методе создается экземпляр класса IPHostEntry, которому присваивается имя компьютера, на котором запущен сервер, при помощи метода Dns. GetHostName. Затем экземпляру класса IPAddress приравнивается значение первого элемента массива AddressList в ipHostInfo. После чего создается IPEndPoint, аргументами которого передаются ipAddress и порт 31111.

ipHostInfo = Dns. GetHostEntry (Dns. GetHostName ());ipAddress = ipHostInfo. AddressList [0];localEndPoint = new IPEndPoint (ipAddress, 31111);

Рисунок 23. Инициализация объектов для создания соединения

Далее создается объект класса Socket, который называется listener. В конструктор класса передаются следующие три параметра:

-AddressFamily. InterNetwork. Это означает, что сокет будет использовать сеть интернет для обмена данными.

-SocketType. Stream. Указывает, что тип сокета является поточным.

-ProtocolType. Tcp. Выбор протокола передачи данных tcp.

listener = new Socket (AddressFamily. InterNetwork, SocketType. Stream, ProtocolType. Tcp);

Рисунок 24. Инициализация объекта класса Socket

Затем переменной listener методом Bind привязывается localEndPoint (т.е. локальный адрес компьютера) и методом Listen открывается сокет, готовый принимать новые подключения.

В консоль пишется фраза "Waiting for a connection…", означающая, что к серверу можно подключиться, и что он уже ожидает подключения.

-Callback - делегат AsyncCallback

-State - объект, содержащий сведения о состоянии входящего запроса

Делегат AsyncCallback ссылается на метод AcceptCallback.

static void StartListening ()

{

byte [] bytes = new Byte [1024];ipHostInfo = Dns. GetHostEntry (Dns. GetHostName ());ipAddress = ipHostInfo. AddressList [0];localEndPoint = new IPEndPoint (ipAddress, 31111);listener = new Socket (AddressFamily. InterNetwork, SocketType. Stream, ProtocolType. Tcp);

try

{. Bind (localEndPoint);. Listen (100);

while (true)

{. Reset ();. WriteLine ("Waiting for a connection. ");. BeginAccept (

new AsyncCallback (AcceptCallback),);. WaitOne ();

}

}

catch (Exception e)

{. WriteLine (e. ToString ());

}. WriteLine ("Press a key to continue");. Read ();

}

Рисунок 25. Метод StartListening

В методе AcceptCallback обрабатывается новое входящее подключение. Создается локальный объект класса Socket, который называется так же - listener. Ему, при помощи явного преобразования типов, присваивается свойство AsyncState, объекта IAsyncResult.

Затем создается еще один локальный экземпляр класса Socket, называемый handler. Ему приравнивается возвращаемое значение метода EndAccept объекта listener.

После этого объявляется и инициализируется новый объект внутреннего класса StateObject. Его полю workSocket присваивается handler. В пул подключений (List<StateObject> sockets) добавляется этот объект.

У объекта handler вызывается метод BeginReceive, который начинает асинхронный прием данных с объекта handler. Метод BeginReceive имеет множество перегрузок, одна из которых принимает следующие аргументы:

-Buffer - массив типа Byte, который является местоположением памяти для полученных данных.

-Offset - отсчитываемая с нуля позиция в параметре buffer, начиная с которой хранятся принятые данные.

-Size - число принимаемых байтов.

-socketFlags - поразрядное сочетание значений SocketFlags.

-Callback - делегат AsyncCallback, ссылающийся на метод, вызываемый по завершении данной операции.

-State - пользовательский объект, содержащий информацию об операции приема. Этот объект передается делегату EndReceive по завершении операции.

Делегат AsyncCallback ссылается на метод ReceiveCallback.

В методе ReceiveCallback описаны операции, выполняемые при получении сервером каких-либо данных. Поскольку этот метод может выбросить огромную кучу исключений, то все операции необходимо выполнять в конструкции try/catch. Конструкция try/catch используется для обработки исключений, произошедших при выполнении кода.

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

Когда некий участок кода выполняется неправильно и создает исключительную ситуацию путем выбрасывания (throw) объекта класса, который унаследован от класса Exception, но при этом отсутствует блок catch, исключение передвигается дальше по стеку, то есть в метод, который его вызвал. Если же и там нет блока catch, то исключение продолжает передвигаться еще дальше.

Если во всем стеке вызовов нет ни единого блока catch, то программа прекращает свое выполнение.

В блоке try метода ReceiveCallback создается локальный объект класса StateObject и локальный объект класса Socket, которые называются state и client соответственно. Объекту state присваивается значение свойства AsyncState объекта AsyncResult, а затем объекту client приравнивается свойство workSocket объекта state.

Далее, если метод EndReceive объекта client возвращает значение большее, чем нуль, значит сервер получил какие-то данные и необходимо их обработать.

При помощи метода Decode, данные расшифровываются и строковое значение возвращается переменной text.

По задумке, сервер должен получать только два вида сообщений - "@@onConnection#name" и "name##packageName: text". Если сервер, каким-то образом, получит сообщение другого типа, то оно просто не будет обработано, уничтожится и сервер продолжит свою работу.

Здесь сервер проверяет, имеет ли сообщение необходимый вид. Если в сообщении присутствует строка "@@onConnection", то эта строка разделяется сепаратором "#" на две строки, которые добавляются в локальный строковый массив parts. Затем полю name объекта state присваивается вторая строка (parts [1]).

Иначе, строка так же делится на две сепаратором "#", обе строки добавляются в локальный строковый массив parts. При помощи оператора foreach перечисляются все подключения.

Каждое из которых проверяется на совпадение поля name, к которому приписывается постфикс "-pc", с именем текущего поля state и таким же постфиксом "-pc". Если же они совпали, то вторая часть текста (parts [1]) зашифровывается методом Encode, после чего вызывается метод Send, который отправляет нужному подключению зашифрованное сообщение.

static void ReceiveCallback (IAsyncResult ar)

{

try

{state = (StateObject) ar. AsyncState;client = state. workSocket;

// Read data from the remote device.

int bytesRead = client. EndReceive (ar);

if (bytesRead > 0)

{. buffer = Decode (state. buffer);. sb. Append (Encoding. ASCII. GetString (state. buffer, 0, bytesRead));

string text = state. sb. ToString ();

if (text. Contains ("@@onConnection"))

{

string [] parts = text. Split ('#');. name = parts [1];

}

else

{

string [] parts = text. Split ('#');

foreach (var item in sockets)

{

if (item. name. Equals (state. name + "-pc"))

{

string toSend = Encode (parts [1])(item. workSocket, toSend);

}

}. WriteLine (parts [1]);

}. sb. Clear ();. BeginReceive (state. buffer, 0, StateObject. BufferSize, 0,new AsyncCallback (ReceiveCallback), state);

}

}

catch (Exception e)

{. WriteLine (e. ToString ());

}

}

Рисунок 26. Метод ReceiveCallback

Метод Send отправляет данные нужному подключению.

Этот метод принимает два параметра:

-handler - объект класса Socket.

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

-data - строковая переменная.

Хранит данные, которые необходимо отправить.

Строковая переменная data преобразуется в массив байт, после чего вызывается метод BeginSend объекта handler. Метод BeginSend имеет несколько перегрузок, одна из которых принимает следующие параметры:

-buffer. Массив типа Byte, который содержит передаваемые данные.

-offset. Отсчитываемая с нуля позиция в параметре buffer, с которой начинается отправка данных.

-size. Количество байт для записи.

-socketFlags. Поразрядное сочетание значений SocketFlags.

-callback. Делегат AsyncCallback.

-state. Объект, содержащий сведения о сотоянии данного запроса.

static void Send (Socket handler, String data)

{

byte [] byteData = Encoding. ASCII. GetBytes (data);. BeginSend (byteData, 0, byteData. Length, 0,new AsyncCallback (SendCallback), handler);

}

Рисунок 27. Метод Send

Делегат AsyncCallback ссылается на метод SendCallback. В этом методе данные отправляются подключению.

Сначала создается локальный экземпляр класса Socket, handler, которому приравнивается свойство AsyncState объекта IAsyncResult. Затем создается локальная переменная bytesSent, которой приравнивается возвращаемое значение метода EndSend объекта handler. Этот метод завершает передачу данных подключению.

В консоль приложение отправляет отчет об отправленных байтах. Затем уничтожается локальный объект handler.

static void SendCallback (IAsyncResult ar)

{

try

{handler = (Socket) ar. AsyncState;

int bytesSent = handler. EndSend (ar);. WriteLine ("Sent {0} bytes to client.", bytesSent);. Shutdown (SocketShutdown. Both);. Close ();

}

catch (Exception e)

{. WriteLine (e. ToString ());

}

}

Рисунок 28. Метод SendCallback

Также, в этом классе имеется метод Main. Это самый главный метод, с которого начинает любая программа, написанная на языках C#, Java, C++ и многих других известных языках.

В этом методе всего лишь вызывается метод StartListening.

static void Main (String [] args)

{();

}

Рисунок 29. Метод Main

2.3 Безопасность разработанной системы

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

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

Для обеспечения конфиденциальности информации в данной системе используется XOR-шифрование.(исключающее ИЛИ) - это логическая булева операция. В языках программирования обозначается знаком ^ (циркумфлекс). Выполняется с двумя битами (a и b). Результат выполнения этой операции равняется 1 (истина), если один из битов равен 1. Во всех остальных случаях результатом будет 0 (ложь).

Таблица 1. XOR-операции

aba ^ b000011101110

Шифрование на основе операций XOR использует функцию:


где k - выступает в роли ключа.

Это шифрование является обратимым, то есть его возможно дешифровать, при наличии ключа. Методы шифрования и дешифрования описаны во все трех приложениях. Ключом является случайно сгенерированный ранее набор символов "ppCS3b1".

Метод шифрования:

static byte [] encode (String text) {

string pKey = "ppCS3b1";

byte [] txt = text. getBytes ();

byte [] key = pKey. getBytes ();

byte [] res = new byte [text. length ()];

for (int i = 0; i < txt. length; i++) {[i] = (byte) (txt [i] ^ key [i % key. length]);

}

return res;

}

Рисунок 30. Метод encode

Метод дешифрования:

public static String decode (byte [] pText) {

string pKey = "ppCS3b1";

byte [] res = new byte [pText. length];

byte [] key = pKey. getBytes ();

for (int i = 0; i < pText. length; i++) {[i] = (byte) (pText [i] ^ key [i % key. length]);

}

return new String (res);

}

Рисунок 31. Метод decode

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

3. Результаты тестирования

Тестирование проводилось на разных устройствах и компьютерах. Ниже приведена таблица с этими устройствами.

Таблица 2. Устройства для тестирования

№ Уст-ваAndroid-устройствоПК клиентаПК сервер1Samsung Galaxy S4 ОS Android 4.4.4 (KitKat) Процессор Samsung Exynos 5410, 1600 МГц Объем ОЗУ 2гбМП ASUS Z97-K ЦП Intel Core i5 Skylake Объем ОЗУ 8гбМП ASUS Z9NA-D6C ЦП Intel Core i5 Объем ОЗУ 16гб2Sony Xperia Z3 OS Android 5.1.1 (Lolipop) Процессор Qualcomm Snapdragon 801 MSM8974AC, 2500 МГц Объем ОЗУ 3гбМП ASUS M5A97 LE R2.0 ЦП Intel Core i5 Haswell Объем ОЗУ 8гбМП ASUS Z9NA-D6C ЦП Intel Core i5 Объем ОЗУ 16гб3OnePlus One OS Android 5.1.1 (Lolipop) Процессор Qualcomm Snapdragon 801, 2500 МГц Объем ОЗУ 3гбМП MSI H81M-P33 ЦПAMD FX Vishera Объем ОЗУ 4гб МП ASUS P10S-I ЦП Intel Core i7 Объем ОЗУ 16гб4HTC Desire 326G OS Android 4.4.4 (KitKat) Процессор Spreadtrum SC7731G Объем ОЗУ 1гбМП ASUS X99-DELUXE II ЦП Intel Core i7 Devil's Canyon Объем ОЗУ 16гбМП ASUS Z9NA-D6C ЦП Intel Core i7 Объем ОЗУ 16гб5LG G4s H736 OS Android 5.1.1 (Lolipop) Процессор Snapdragon 815, 1500 МГцМП Supermicro X10SLL+-F Intel Pentium Haswell Объем ОЗУ 4гбМП ASUS Z10PA-D8 ЦП Intel Core i3 Объем ОЗУ 4гб

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

-скорость отправки/получения данных

-задержка между двумя операциями

-максимальная нагрузка

Ниже приведена таблица с результатами тестирования.

Таблица 3. Результаты тестирования

№ Связки№ Android-устройства (см. Таблицу 1) № ПК клиента (см. Таблицу 1) № ПК Сервера (см. Таблицу 1) Оценка (0-10) 11119,521218,931338,141438,851557,962319,172419,083139,193439,2103557,5113429,3123458,5134337,1144236,9154437,0164526,9174147,5185557,9195448,9205438,9

Средняя оценка - 8,3.

Основные проблемы возникли на Android-устройстве №4 (HTC Desire 326G), ПК №5 (МП Supermicro X10SLL+-F, Intel Pentium Haswell, Объем ОЗУ 4гб) и серверным компьютером №5 (МП ASUS Z10PA-D8, ЦП Intel Core i3, Объем ОЗУ 4гб). На HTC Desire приложение часто выходило из строя по непонятным причинам. Некоторые уведомления не отправлялись. Один раз сервис вообще не создался. На ПК №4 основные проблемы были связаны с задержкой между двумя уведомлениями. Не смотря на то, то они были отправлены с интервалом в 1 секунду, приложение отображало из с интервалом в 2,5-3 секунды. К серверному компьютеру №5, в отличие от остальных, доступ осуществлялся удаленно, так как компьютер находился на расстоянии нескольких тысяч километров. Из-за большого расстояния скорость отправки/приема данных была хуже, чем у остальных.

Несмотря на это, система отлично прошла тестирование и готова к эксплуатации.

4. Экономическое обоснование дипломного проекта

Информация о проекте. Полное наименование проекта - разработка приложения для автоматического обеспечения передачи оповещения с мобильного телефона на компьютер.

Характер проекта:

Вспомогательный

Направление использования инвестиций:

Исследования и разработки

Продукция (услуги):

Наименование продукции (услуги) - создание системы синхронизации уведомлений при помощи языков программирования Java и C#.

Назначение и основные характеристики - "Система синхронизации уведомлений" ориентирована на повседневное использование любым физическим лицом.

Масштабы и направления:

Весь мир

Потребительская характеристика:

Любой владелец android-смартфона и ПК

Привлекательные характеристики:

Сокращение времени.

Характеристика рынка сбыта продукции (услуг):

Основной потребитель - любой владелец смартфона с ОС Android.

Обеспеченность сбыта продукции (услуг):

Отсутствует

Конкуренция:

Основным конкурентом является студия Pushbullet с их одноименным проектом.

4.1 Расчет себестоимости создания системы

Для расчета затрат на программные средства имеются следующие исходные данные:

-стадии разработки системы;

-нормативы для определения трудоемкости и средней численности разработчиков по каждому этапу работы;

-заработную плату разработчиков;

-стоимость машинного часа работы оборудования;

-время работы оборудования при разработке программы.

Затраты на разработку программы - себестоимость программы, определяется по формуле:


где Зо. м - затраты на основные материалы, применяемые при разработке программы, руб.;

ТЗР - транспортно-заготовительные расходы, руб.;

Зэл. - затраты на силовую электроэнергию, руб.;

Ззп - затраты по заработной плате специалистам, участвующим в разработке программы, с учетом страховых взносов, руб.;

Зо - затраты, связанные с работой оборудования, руб.;

НР - накладные расходы, руб.

Таблица 4 - Затраты на материалы, полуфабрикаты, покупные изделия

Наименование сырья, материалов, топливаЕдиница измеренияКол-во израсходованного материала единицПланово-заготовительная цена, рублей за единицуСумма, руб. 1Флэш-накопитель 4 Гбшт. 1250250 2Бумагаупаковка22004003Ручкишт. 211224Карандашишт. 1775Папкашт. 180806Дыроколшт. 11001007Ластикшт. 11010ИТОГО: 869

Исходя из таблицы 5, затраты на основные материалы составили 869 руб.

Транспортно-заготовительные расходы составляют исходя из затрат на основные материалы. Они определяются по формуле:

ТЗР = 869 * 3,4/100 = 29,546 (руб.)

Затраты на силовую электроэнергию рассчитываются по формуле:

гдеTэл - тариф на электроэнергию,

КПД - коэффициент полезного действия оборудования;эф - эффективный фонд работы оборудования;- Мощность оборудования.

Таким образом:

Зэл. = 3.9*0,9*132*0,8 = 370,656

Затраты по заработной плате определяются по формуле:

ФЗП = ФОЗП + ФДЗП (руб.), (5)

где ФОЗП - фонд основной заработной платы;

ФДЗП - фонд дополнительной заработной платы;

ФЗП = 14998,54 +916,3=15914,84 руб.

Фонд основной заработной платы определяется по формуле:

ФОЗП = ФЗП тар. + П (руб.), (6)

где ФЗП тар. - тарифная (прямая) заработная плата;

П - премия.

ФОЗП = 15914,84+1000 =16914,84 руб.

Прямая заработная плата определяется по формуле:

ФЗП тар. = (Ом * tшт.) / (Дм. * d) (руб.), (7)

где Ом - оклад за месяц;шт. - затраты времени на разработку этапа программы, час;

Дм. - количество рабочих дней в месяце;- Продолжительность рабочего дня.

ФЗП тар1. = (10000 * 12) / (24 * 8) = 625руб.

ФЗП тар2. = (10000* 89) / (24 *8) = 4635,41руб.

ФЗП тар3. = (10000 * 20) / (24*8) = 1041,66руб.

ФЗП тар4. = (10000 *19) / (24*8) = 989,58руб.

ФЗП тар = (10000 * 140) / (24 * 8) = 7291,66руб.

Таблица 5 - Расчет основной заработной платы

Этапы работыТрудоемкость (час) РасчетЗатраты (рублей) Постановка задачи12 (10000 * 12) / (24 * 8) 625Разработка приложений89 (10000* 89) / (24 *8) 4635,41Отладка приложений20 (10000 * 20) / (24*8) 1041,66Выпуск технической документации19 (10000 *19) / (24*8) 989,58Итого140 (10000 * 140) / (24 * 8) 7291,66

Премия рассчитывается от прямого заработка.

П = %П * ФЗП тар. / 100% (руб.), (8)

П = 32* 15914,84/100 = 5092,74 руб.

Фонд дополнительной заработной платы рассчитывается от фонда основной заработной платы и определяется по формуле:

ФДЗП = % ФДЗП * ФОЗП / 100% (руб.), (9)

ФДЗП = 8 * 16914,84/100 = 1353,18 руб.

Страховые взносы (СВ) рассчитываются от суммы фонда основной и фонда дополнительной заработной платы определяются по формуле:

СВ = (ФОЗП + ФДЗП) *СВ%/100% (руб.), (10)

СВ = (16914,84 + 916,3) * 30.2/100 = 5385 руб.

Затраты по заработной плате специалистам, участвующим в разработке программы, с учетом страховых взносов рассчитываются по формуле:

Ззп = ФЗП + СВ (руб.), (11)

Ззп = 15914,84 + 5385 = 21299,84 руб.

Затраты, связанные с работой оборудования определяются по формуле:

где tоб. - время работы оборудования при составлении программы (час);

Сэ. о. - стоимость часа эксплуатации оборудования.

Зо = tоб. * Сэ. о. (руб.), (12)

Зо = 132 * 2.14 = 282,48 руб.

где tоб. - время работы оборудования при составлении программы (час);

Сэ. о. - стоимость часа эксплуатации оборудования.

Стоимость часа эксплуатации оборудования определяется по формуле:

Сэ. о. = (Цоб. / Т) * tшт. (руб.), (13)

где Цоб. - стоимость оборудования;

Таблица 6 - Стоимость оборудования

Наименование оборудованияСрок эксплуатацииКоличество единицСтоимость единицы, руб. Суммарная стоимость оборудования, руб. Системный блок CoolerMaster511700017000Монитор LG 216122002200Комплект мышь 4tech X7, клавиатура SpeedLink11800800Windows 810110001000ИТОГО: 21000

Т - срок эксплуатации оборудования;

Срок эксплуатации компьютера рассчитывается следующим образом:

Т =tэкс. * Дг. * d (часов), (14)

где tэкс. - количество лет эксплуатации оборудования;

Дг. - количество рабочих дней

Срок эксплуатации системного блока:

Тс. б = 5 * 247 * 8 = 9880 час.

Срок эксплуатации монитора:

Тм. = 6 * 247 * 8 = 11856 час.

Срок эксплуатации мыши и клавиатуры:

Тм. к = 1 * 247 *8 = 1976 час.

Срок эксплуатации оперативной системы:

То. с = 10 * 247 * 8 = 19760 час.

Стоимость часа эксплуатации системного блока:

Сэ. с. б = 15000/9880 = 1,51 руб/час

Стоимость часа эксплуатации монитора

Сэ. м = 2200/11856 = 0,18 руб/час

Стоимость часа эксплуатации мыши и клавиатуры:

Сэ. м. к = 800/1976 = 0,40 руб/час

Стоимость часа эксплуатации операционной системы:

Сэ. о. с = 1000/19760 = 0,05 руб/час

Сэ. o = 1,51+0,18+0,40+0,05 = 2.14 руб/час

Зо1 = 2,14 * 93 = 199,02 руб.

Зо2 = 2,14 * 20 = 42,8 руб.

Зо3 = 2,14 * 19 = 40,66 руб.

Зобщ =199,02 +42,8 +40,66 = 282,48 руб

Таблица 7 - Расчет амортизационных отчислений

Этапы работыТрудоемкость (час) РасчетЗатраты (рублей) Разработка приложений892,14 * 89190,46Отладка приложений202,14 * 2042,8Выпуск технической документации192,14 * 1940,66Итого: 132190,46+42,8+40,66 273,92

Накладные расходы составляют рассчитываются от основной заработной платы и определяются по формуле:

НР=ФОЗП * %НР/100% (руб.) (15)

НР = 14998,54 * 33/100 = 4949.51 руб.

Сп = 897,54 + 370,656 + 21299,84 + 282,48 + 4949,51 = 27800,02 руб.

Калькуляция себестоимости программы представлена в таблице 5.

Таблица 8 - Калькуляция себестоимости создания сайта

Статьи затратЗатраты (руб.) Затраты на материалы, в том числе: основные материалы; транспортно-заготовительные расходы.897,54 869 29,54Затраты на силовую электроэнергию370,656Затраты на заработную плату, в том числе: фонд основной заработной платы; фонд дополнительной заработной платы; страховые взносы21299,84 14998,54 916,3 5385Затраты на эксплуатацию оборудования282,48Накладные расходы4949.51Полная себестоимость27800,02

Прибыль определяется по формуле:

Прибыль = Сп*%R/100% (руб.), (16)

где %R - рентабельность создания сайта

П = 37177 * 26/100 = 9666 руб.

Отпускная цена определяется по формуле:

Ц = Сп + Прибыль (руб.) (17)

Ц = 37177 + 9666 = 46843 руб.

4.2 Расчет срока окупаемости системы

Срок окупаемости вычисляется по формуле:

Ток. = К2 - К1/ С2 - С1 (лет) (18)

Ток. = (21000-15000) / ( (37177-20000) * 16) = 0,021

где ДК - разница между затратами, которые были и которые получились в результате разработки программы;

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

= T/t (руб) (19)

Где t - трудоемкость создания программы, дни;

Т - количество дней работы оборудования в год, дни.

4.3 Анализ действующих цен на рынке

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

Таблица 9 - Цены на создание ПО

Название этапаСтоимость моей работыДоля затрат, %Стоимость работ фирмы - конкурента (Pushbullet) рубДоля затратРазработка ПК-клиента1800034,932100031,91Разработка Android-приложения 2300044,633300050,16Разработка сервера45308,7955008,36Тестирование600311,656300 9,57Всего за создание ПО5153310065800100

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

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

5. Охрана окружающей среды и техника безопасности

В помещении, в котором находится электронно-вычислительная техника, должно быть и естественное, и искусственное освещение. Естественным освещением называют свет, проникающий в помещение через светопроемы со стороны севера или северо-востока. Тем самым обеспечивается коэффициент естественного освещения (КЕО) в пределах 1,5 %.

Одно рабочее место для пользователя ПЭВМ должно занимать место, площадью не менее 6,0 кв. м., а объемом не менее 20,0 куб. м.

Материалом внутренней отделки помещения, в котором располагается электронно-вычислительная техника, должен являться любой диффузно-отражающий материал с коэффициентом отражения для потолка - 0,7 - 0,8; для стен - 0,5 - 0,6; для пола - 0,3 - 0,5.

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

Как правило, в помещениях применяется боковое естественное освещение.

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

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

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

Поверхности рабочего стола для размещения рабочего документа должна иметь освещенность равную 300 - 500 лк (люкс). Если же установлено местное освещение, оно не должно создавать бликов на поверхности экрана и увеличивать освещенность экрана более 300 лк.

Прямая блесткость от источников освещения должная быть ограничена. К тому же яркость светящихся поверхностей не должна быть более 200 кд/ кв. м.

Неравномерность яркости в поле зрения электронно-вычислительной техники необходимо ограничивать. Между рабочими поверхностями должно быть соотношения яркости не превышающее 3: 1 - 5: 1, а между рабочими поверхностями и поверхностями стен и оборудования 10: 1.

Для того, чтобы осветить помещение, в котором расположена электронно-вычислительная техника, нужно использовать светильники серии ЛП036 с рефлекторами и укомплектованными высокочастотными пускорегулирующими аппаратами. Применение светильников без рассеивателей и рефлекторов не допускается. Светильники общего освещения должны иметь яркость в зоне углов излучения от 50° до 90° с вертикалью в продольной и поперечной плоскостях. Защитный угол светильников должен составлять не менее 40°.

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

Коэффициент пульсации не должен превышать 5 %, что должно обеспечиваться применением газоразрядных ламп в светильниках общего и местного освещения с высокочастотными пускорегулирующими аппаратами (ВЧ ПРА) для любых типов светильников. При отсутствии светильников с ВЧ ПРА лампы многоламповых светильников или рядом расположенные светильники общего освещения включать на разные фазы трехфазной сети.

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

Схемы размещения рабочих мест ПЭВМ! должны учитывать расстояния между рабочими столами с видеомониторами (в направлении тьма поверхности одного видеомонитора и экрана другого видеомонитора), которое должно быть не мене 2,0 м, а расстояние между боковыми поверхностями видеомониторов - не менее 1,2 м.

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

Экран монитора должен находиться на расстоянии 600 - 700 мм, но не ближе 500 мм с учетом алфавитно-цифровых знаков и символов.

На рис.7 представлена схема расположения рабочих мест.

Рисунок 32. Схема расположения рабочих мест относительно светопроемов:

1 - системный блок; 2 - монитор; 3 - клавиатура; 4 - кресло; 5 - стол; 6 - подставка.

В таблице 10 представлены параметры одноместного стола.

Таблица 10 - Высота одноместного стола для занятий с ПЭВМ и В ДТ

Рост человека в обуви, смВысота над полом, ммповерхность столапространство для ног, не менее130520400131-145580520146-160640580161-175700640 выше 175760700

Заключение

В ходе выполнения дипломной работы были выполнены следующие задачи: получены знания об основных принципах разработки программного обеспечения для ОС Android, таких как xml разметка, принципы работы приложений, особенности работы с мобильными приложениями, работа с TCP-соединением и передачей данных через сеть интернет, разработка сервисов (служб) и задач, выполняемых в фоновом режиме. Целевой платформой была платформа Android версии 4.0.0. Целевым языком для разработки - язык Java версии 1.6. Были закреплены знания о работе с TCP-соединением на языке C#. Изучена разработка асинхронных соединений и асинхронной работы с данными.

Для реализации поставленной задачи были использованы следующие средства: среда разработки Microsoft Visual Studio 2015 Community edition и Android Studio 2.1 В процессе выполнения курсовой работы соответствующая система была разработана и доведена до рабочего, пригодного для эксплуатации, состояния.

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

В перспективе можно перевести систему на модель end-to-end шифрования, что позволит ей работать без наличия каких-либо серверов. Это позволит снизить затраты на содержание и обслуживание серверного компьютера, а также исключит вероятность отказа сервера, по различным причинам, что может привести к остановке всей системы целиком.

В разделе "Экономическое обоснование дипломного проекта" были приведены все расчеты, связанные с затратами на реализацию проекта, а также рассчитана себестоимость системы.

В разделе "Охрана окружающей среды и техника безопасности" был произведен расчет искусственной освещенности помещения, а также требования к организации и оборудованию рабочих мест ПЭВМ.

Список используемых источников

1.Албахари Дж., Албахари Б. C# 5.0. Карманный справочник, 2013 - 288 стр.

2.Брюс Эккель. Филосифия Java 4-е издание, 2014 - 1168 стр.

3.Герберт Шилдт. Java. Руководство для начинающих, 2012 - 624 стр.

4.Дейтел П. Android для разработчиков, 2015 - 384 стр.

5.Джеффри Рихтер. CLR via C#. Программирование на платформе Microsoft.net Framework 4.5 на языке C#.4-е изд., 2016 - 896 стр.

6.Дэвис А. Асинхронное программирование в C# 5.0, 2013 - 120 стр.

7.Крйег Хант. TCP/IP. Сетевое администрирование, 2006 - 816 стр.

8.Мартин Р., Мартин М. Принципы, паттерны и методики гибкой разработки на языке C#, 2011 - 768 стр.

9.Нейгел К., Ивьен Б. C# 5.0 и платформа.net 4.5 для профессионалов, 2014 - 1440 стр.

10.Роберт Лафоре. Ктуры данных и алгоритмы Java, 2013 - 704 стр.

11.Станислав Давыдов, Алексей Ефимов. IntelliJ IDEA. Профессиональное программирование на Java, 2005 - 800 стр.

13.Алексей Голощапов. Google Android. Системные компоненты и сетевые коммуникации, 2013 - 384 стр.

14.Рик Роджерс, Джон Ломбардо. Android. Разработка приложений, 2010 - 400 стр.

15.Тереза Нейл. Мобильная разработка. Галерея шаблонов, 2013 - 216 стр.

16.Виктор Олифер, Наталия Олифер. Компьютерные сети. Принципы, технологии, протоколы: Учеб. пособие - Изд.: Питер, 2016 - 992 стр.

17.Дж. Клейнберг Дж., Е. Тардос. Алгоритмы: разработка и применение. Классика Computers Science - Изд.: Питер, 2016 - 800 стр.

18.Дмитрий Мельников. Системы и сети передачи данных, 2015 - 624 стр.

19.Борис Соболь, Александр Доманин. Сети и телекоммуникации: Учеб. пособие - Изд.: Феникс, 2015 - 192 стр.

20.Энтони Уильямс. Параллельное программирование на C++ в действии. Практика разработки многопоточных программ, 2013 - 672 стр.

.Многопоточность в C#. 2016. [Электронный ресурс] URL: #"justify">.Алгоритмы и структуры данных. 2016. [Электронный ресурс] URL: #"justify">.Форум программистов. 2016. [Электронный ресурс] URL: #"justify">.База знаний всех классов и интерфейсов языка Java. 2016. [Электронный ресурс] URL: #"justify">.Портал, посвященный IT-сфере. 2016. [Электронный ресурс] URL: #"justify">.Сеть разработчиков Microsoft. 2016. [Электронный ресурс] URL: #"justify">.Примеры алгоритмов. 2016. [Электронный ресурс] URL: #"justify">.Портал о разработке для ОС Android. 2016. [Электронный ресурс] URL: #"justify">.Портал, посвященный IT-сфере. 2016. [Электронный ресурс] URL: #"justify">.Сайт о программировании. 2016. [Электронный ресурс] URL: http://tproger.ru/ Режим доступа: свободный. Дата обращения: 10.05.2016

Похожие работы

 

Не нашел материала для курсовой или диплома?
Пишем качественные работы
Без плагиата!