Изучение методов разработки программного обеспечения для создания UDP сокетов и протоколов

Курсовой проект - Компьютеры, программирование

Другие курсовые по предмету Компьютеры, программирование

· сети. Передаётся списку контактов при закрытии приложения.:room:public_key - команда, обозначающая, что посылающий её клиент хочет открыть зашифрованное приватное соединение в комнате room с открытым ключом public_key.:room:public_key - этой командой должен ответить клиент в случае согласия на установление защищённого соединения в комнате room с открытым ключом public_key.:room:message - эта команда служит для передачи сообщений (message) между пользователями. Сообщение доставляется в комнату room.

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

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

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

Функциональная схема шифрования с открытым ключом представлена на рисунке 3.2.

 

Рисунок 3.2 - Схема шифрования с открытым ключом

 

Алгоритм шифрования сообщения следующий:

пользователь В выбирает пару ключей (e,d) и шлёт ключ шифрования e (открытый ключ) пользователю А по открытому каналу, а ключ расшифрования d (закрытый ключ) защищён и секретен (он не должен передаваться по открытому каналу);

чтобы послать сообщение m пользователю В, пользователь А применяет функцию шифрования, определённую открытым ключом e: Ee(m) = c, c - полученный шифротекст;

пользователь В расшифровывает шифротекст c, применяя обратное преобразование Dd, однозначно определённое значением d.

4. Описание основных модулей и функций программы

 

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

/**

* Идентификатор команды "маячка". Передаётся для

* обозначание, что клиент в сети.

* Пример: PRSN

*/static final String CMD_PRESENT = "PRSN";

/**

* Идентификатор команды смены ника.

* Пример: NICK:nick

*/static final String CMD_NICK = "NICK";

/**

* Идентификатор команды синхронизации. В команде

* передаётся список названий всех комнат, в

* которых состоит клиент.

* Пример: SYNC:room1:room2:...

*/static final String CMD_SYNC = "SYNC";

/**

* Идентификатор команды выхода. Команда широко-

* вещательно отсылается при выходе из клиентской

* программы.

* Пример: QUIT

*/static final String CMD_QUITE = "QUIT";

/**

* Идентификатор команды инициализации защищённого

* соединения. Вместе с командой отсылается открытый

* ключ, с помощью которого будут шифроваться исходящие

* сообщения.

* Пример: INIT:public_key

*/

public static final String CMD_PRV_INIT = "INIT";

/**

* Идентификатор команды подтверждения установления

* защищённого соединения. Вместе с командой передаётся

* открытый ключ для шифровки входящих сообщений.

* Пример: ACPT:public_key

*/static final String CMD_PRV_ACCEPT = "ACPT";

/**

* Идентификатор команды входящего сообщения. Вместе

* с командой передаётся название комнаты, в которую

* адресовано сообщение, и само сообщение.

* Пример: MSG:room:message

*/static final String CMD_MESSAGE = "MSG";

Приём UDP пакетов из UDP сокета, слушающего определённый порт, организован в виде отдельной нити в программе. Эту нить запускает метод runRecievingProcess(), описание которого представлено ниже:

/**

* Данный метод запускает процесс приёма входящих

* UDP пакетов в отдельной нити.

*/void runRecievingProcess() {Thread(new Runnable() {

@Overridevoid run() {ds = null;packet = null;[] buf = new byte[BUF_LENTH];

try {

// создаём UDP совет, слушающий входящие соединения

// на порт port.= new DatagramSocket(port);

} catch (SocketException e) {.printStackTrace();

}

// Создаём пакет на основе буфера и указания его длины,

// в который будет записан входящий пакет данных.

packet = new DatagramPacket(buf, buf.length);

// Бесконечный цикл для приёма всех входящих UDP пакетов.

while(true) {{

// Принимаем UDP пакет. .receive(packet);

} catch (IOException e) {

e.printStackTrace();

}

// Т.к. буфер данных, в который записывается сообщение

// из пришедшего пакета, всегда дополняется до максимума,

// необходимо выделить из него лишь значимую часть.

byte[] shortBuf = new byte[packet.getLength()];.arraycopy(buf, 0, shortBuf, 0, packet.getLength());mes = new String(shortBuf);

// Выводим в консоль пришедшее сообщение из пакета..out.println(mes);

// Передаём сообщение и адрес, откуда оно пришло, в

// специальный метод для дальнейшего анализа данных.

parseMessage(packet.getAddress().getHostAddress(), mes);

}

}

}).start(); // Запуск нити

}

Чтобы что-то принять, нужно что-то отправить. Для отправки UDP пакетов служит методы sendMessage(), описанный ниже:

/**

* Данный метод передаёт UDP пакеты через UDP сокет.

*

* @param message сообщение для передачи. Может быть null

* при типах сообщения отличных от CMD_MESSAGE.

* @param roomName комната, в которую необходимо передать сообщение.

* Может быть null, тогда сообщение будет передано широковещательно.

* @param type тип сообщения.

*/public void sendMessage(String message, String roomName, String type) {packet = null;(type == null || (message == null && type == CMD_MESSAGE))new NullPointerException();(message == null)

message = "";{

// Подготовливаем сообщение в зависимости от его типа.

message = prepareMessage(message, roomName, type);

// Проверяем, находится ли пользователь в той комнате,

// в которую нужно передать сообщение.room = getRoomByName(roo