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

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    254,03 Кб
  • Опубликовано:
    2012-08-14
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

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

Введение

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

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

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

программы-чаты для общения в локальных сетях;

чаты, реализованные поверх сторонних протоколов (например чат, использующий ICQ);

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

Разрабатываемая программа относится к чатам, предназначенным для общения в локальной сети, и имеет некоторые преимущества перед существующими аналогами (например, Vypress Chat, Intranet Chat):

программа может запускаться на различных операционных системах и платформах, т.к. написана на языке Java;

программа поддерживает шифрование личных сообщений на основе асимметричного алгоритма RSA.

1. Описание протокола

Протокол UDP (англ. User Datagram Protocol - протокол пользовательских датаграмм) - это транспортный протокол для передачи данных в сетях IP без установления соединения. Он является одним из самых простых протоколов транспортного уровня модели OSI.не гарантирует доставку пакета, поэтому аббревиатуру иногда расшифровывают как Unreliable Datagram Protocol (протокол ненадёжных датаграмм). Это позволяет ему гораздо быстрее и эффективнее доставлять данные для приложений, которым требуется большая пропускная способность линий связи, либо требуется малое время доставки данных.

Первые 64 бита (8 байт) датаграммы (рис. 1.1) представляют собой UDP-заголовок, остальные биты - данные сообщения:

Рисунок 1.1 - Структура UDP пакета

Значение поля «длина датаграммы» указывает на длину всего UDP-сообщения, то есть, включая и UDP-заголовок. Измеряется в октетах (байтах).

Для вычисления максимальной длины данных в UDP-сообщении необходимо учесть, что UDP-сообщение в свою очередь является содержимым области данных IP-сообщения. Максимальная длина IP-сообщения (с учетом заголовка) равна 65535 октетов. Потому максимальная длина UDP-сообщения (за вычетом минимального IP-заголовка) равна 65535 − 20 = 65515 октетов. Длина заголовка UDP-сообщения равна 8 октетам, следовательно, максимальная длина данных в UDP-сообщении равна 65515 − 8 = 65507 октетов (рис. 1.2).

Рисунок 1.2 - Максимальный размер UDP сообщения

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

2. Описание выполняемой задачи

Разрабатываемая программа должна предоставлять пользователю следующие основные возможности:

писать в общий чат, видимый всеми другими пользователями;

видеть список всех участников общения на текущий момент (их ники, IP-адреса и общее количество);

менять свой ник;

вставлять в свои сообщения смайлы;

иметь возможность ручного (по нажатию кнопки) и автоматического (по таймеру) обновления списка пользователей в сет;

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

Защищённое соединение подразумевает под собой один из способов асинхронного шифрования - алгоритм RSA. Главным преимуществом асинхронного шифрования перед синхронным шифрованием заключается в том, что в первом случае не требует защищённого канала связи между абонентами для передачи ключа расшифровки данных. Ключ для шифрования данных передаётся по не защищённому каналу, с помощью него происходит шифрование данных. Но чтобы расшифровать данные, необходим также закрытый ключ, который держится в секрете и никуда не передаётся.

3. Структура программы

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











Рисунок 3.1 - Структурно-функциональная схема программы

Сетевой модуль является основным модулем, организующим информационное взаимодействие с другими программами-клиентами. Этот модуль передаёт следующие команды:- эта команда обозначает, что передающий её клиент находится в сети. Нужна для обновления списков контактов клиентов. Посылается с определённым интервалом или же по команде пользователя.:room1:room2… - эта команда служит для оповещения сетевых клиентов о том, что пославший её клиент находится комнатах room1, room2 и т.д.:nick - команда служит для оповещения остальных сетевых клиентов о смене ника пользователя.- эта команда обозначает, что передающий её клиент выходит из сети. Передаётся списку контактов при закрытии приложения.: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(roomName);

// Необходимо определить список адресов, на которые

// будем посылать UDP пакеты.<String> addrs = null;

if(room != null) {

// Если сообщение адресовано в конкретную комнату, то

// выделяем список тех, кто в ней находится.= room.getAddresses();

} else {

// Иначе устанавливаем список в широковещательный.= BROADCAST;

}

// Преобразование адреса из символьного представления в

// понятный программе.inetAddr = InetAddress.getByName(addr);

// Пропускаем передачу пакета к себе же.

if(inetAddr.getHostAddress().equals(localAddress))

continue;

// Формируем UDP пакет для передчи. Методу передаются сообщение

// в виде байтового массива, длина сообщения, сетевой адрес

// назначения, а также порт.= new DatagramPacket(message.getBytes(), message.length(),

inetAddr, port);

// Отсылаем пакет через сокет.

sendingSocket.send(packet);

}

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

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

} catch (IOException e) {

e.printStackTrace();

}

}

Перед отправкой сообщения, оно формируется таким способом, чтобы было понятно другим подобным программам клиентам. Этим формированием занимается метод prepareMessage(), описанный ниже:

/**

* Данный метод предназначен для подготовки сообщения к

* передачи в зависимости от его типа.

*

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

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

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

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

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

* @return подготовленнное к передаче сообщение.

*/String prepareMessage(String message, String roomName, String type) {mes = null;

// Тип сообщения CMD_PRESENT

// Пример: PRSN:nick(type.equals(CMD_PRESENT)) {

// Добавляем к идентификатору ник пользователя.

mes = CMD_PRESENT+":"+nick;

}

// Тип сообщения CMD_SYNC

// Пример: SYNC:room_1:@room_2...if(type.equals(CMD_SYNC)) {

mes = CMD_SYNC;

// Добавляем к идентификатору список всех комнат,

// в которых находится пользователь.(NetRoom r : rooms)+= ":"+r.getName();

}

// Тип сообщения CMD_NICK

// Пример: NICK:nickif(type.equals(CMD_NICK)) {

// Добавляем к идентификатору ник пользователя.= CMD_NICK+":"+nick;

}

// Тип сообщения CMD_QUIT

// Пример: QUITif(type.equals(CMD_QUITE)) {= CMD_QUITE;

}

// Тип сообщения CMD_SYNC

// Пример: MSG:room:messageif(type.equals(CMD_MESSAGE)) {room = getRoomByName(roomName);(room != null) {

// Если у комнаты стоит идентияикатор защищённого соединения,

// то сообщение перед отправкой необходимо зашифровать.(room.isProtected()) {

// Проверяем, пришёл ли к нам открытые ключ от инициатора

// защищённого соединения.(room.getExternalPublicKey() != null) {

// Зашифровываем сообщение с помощтю полученного открытого ключа.

message = RSACipher.encode(message, room.getExternalPublicKey());

} else {

// Если кдюча нет, то посылаем в представление сообщение об ошибке.

// Пример: from:INFO:room:message(localAddress

+":"+INFO

+":"+room.getName()

+":"+"Ошибка при кодировании. Нет открытого ключа.");"";

}

}

}

// Добавляем к идентификатору название комнаты,

// в которую оно адресовано, и само сообщение.

mes = CMD_MESSAGE+":"+roomName+":"+message;

}

// Тип сообщения CMD_PRV_INIT

// Находим в спике комнат нужную по названию.

NetRoom room = getRoomByName(roomName);(room != null) {

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

// стороне защищенного соединения для шифрования исходящих

// сообщений.pubKey = room.getKeyPair().getPublic();

// Добавляем к идентификатору название комнаты, в которую

// адресовано ообщение и открытый ключ.

mes = CMD_PRV_INIT+":"+roomName+":"+new String(pubKey.getEncoded());

}

}

// Тип сообщения CMD_ACCEPT

// Пример: ACPT:room:public_keyif(type.equals(CMD_PRV_ACCEPT)) {

// К идентификатору добавляем название комнаты,

// в которой устанавливается защищённое соединение,

// а также само сообщение.= CMD_PRV_ACCEPT+":"+roomName+":"+message;

}mes;

}

После приёма входящего сообщения, его необходимо обработать, для этого служит метод parseMessage(), описанный ниже:

/**

* Парсинг входящих сообщений.

*

* @param from сетевой адрес того, от кого пришло сообщение.

* @param mes само сообщение.

*/void parseMessage(String from, String mes) {

// PRSN:nick(mes.startsWith(CMD_PRESENT)) {

// На маячок нужно ответить синхронизирующим сообщением.

// В нём передаётся список комнат, к которым подключен пользователь.

sendMessage(null, null, CMD_SYNC);

// Передаём команду в систему отображения.

// Пример: from:PRSN:nick(from+":"+mes);

}

// SYNC:room_1:room_2...if(mes.startsWith(CMD_SYNC)) {

String[] split = mes.split(":");

// В цикле перебираем все названия комнат в синхросообщении.

for(int i = 1; i < split.length; i++) {

// Находим нужную комнату.room = getRoomByName(split[i]);

// Добавляем в список адресов комнаты тот,

// от кого пришло это сообщение.

if(room != null).addAddress(from);

}

// Передаём команду в систему отображения.

// Пример: from:SYNC:room_1:room_2...(from+":"+mes);

}

// QUITif(mes.startsWith(CMD_QUITE)) {

// Передаём команду в систему отображения.

// Пример: from:QUIT(from+":"+mes);

}

// NICK:nickif(mes.startsWith(CMD_NICK)) {

// Передаём команду в систему отображения.

// Пример: from:NICK:nick(from+":"+mes);

}

// MSG:room:messageif(mes.startsWith(CMD_MESSAGE)) {[] split = mes.split(":", 3);roomName = split[1];

String message = split[2];

// Находим по имени комнату, в которую адресовано сообщение.

NetRoom room = getRoomByName(roomName);(room != null) {

// Если у комнаты стоит метка о необходимости защищённого

// соединения, то входящее сообщение неоходимо расшифровать.(room.isProtected()) {{

// Расшифровываем входящее сообщение с помощью

// сохранённого закрытого ключа.= RSACipher.decode(message, room.getKeyPair().getPrivate());

} catch (BadPaddingException e) {

// Если случилась ошибка при расшифровке, то передаём

// необходимую информацию в отображение.

// Пример: from:INFO:room:message

fireActionPerformed(localAddress

+":"+INFO

+":"+room.getName()

+":"+"Ошибка при декодировании. Нет ключа или он не верен.");

}

}

// Передаём команду в систему отображения.

}

}

// INIT:room:public_key || ACPT:room:public_keyif(mes.startsWith(CMD_PRV_INIT) || mes.startsWith(CMD_PRV_ACCEPT)) {[] split = mes.split(":", 3);cmd = split[0];roomName = split[1];key = split[2];

NetRoom room = null;

// При инициализации защищённого соединения для какой-либо

// комнаты, необходимо добавить её в список комнат, к которым

// причастен пользователь.(cmd.equals(CMD_PRV_INIT)) {

room = new NetRoom(roomName);.add(room);

} else

// При принятии приглашения на создание защищенного соединения,

// ищем по названию уже существующую комнату.

room = getRoomByName(roomName);(room != null) {

// Проверяем установку флага защищённого соединения..setProtected(true);

// Преобразуем полученный массив байт в открытый.

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

X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(key.getBytes());

try {

// Затем создаётся фабрика ключей на основе нужного алгоритма шифрования.

KeyFactory keyFactory = KeyFactory.getInstance(RSACipher.ALGORITHM);

// И наконец создаётся сам открытый ключ.

PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);

// Устанавливаем его в качестве параетра нужной комнаты.

room.setExternalPublicKey(pubKey);

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

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

}

// В отображение необходимо передавать лишь команду инициализации

// защищённого соединения.(cmd.equals(CMD_PRV_INIT)) {

// Пример: from:INIT:room:public_key

fireActionPerformed(from+":"+cmd+":"+roomName);

// И необходимо сформировать и передать пакет подтверждения

// соединения. А вместе с ним передать ключ для шифровки сообщений.

sendMessage(new String (room.getKeyPair().getPublic().getEncoded()),

roomName, CMD_PRV_ACCEPT);

}

}

}

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

/**

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

* пакетов с определённой периодичностью.

* @param period частота передачи "маяковых" пакетов.

*/run Broadcasting(long period) {timer = new Timer(true);task = new TimerTask() {

@Overridevoid run() {

// Широковещательно передаётся команда PRSN(null, null, CMD_PRESENT);

}

};.schedule(task, 1000, period);

Для реализации защищённых пользовательских каналов методом асинхронного шифрования RSA, используются три метода: encode(), decode() и initKeys(), определённые в классах RSACipher и NetRoom.

Метод encode() шифрует предоставленные ему данные на основе переданного открытого ключа. Описание метода представлено ниже:

/**

* Метод шифрует переданные данные на основе открытого ключа.

* @param data данные для шифрования.

* @param publicKey открытый ключ.

* @return зашифрованное сообщение.

*/static String encode(String data, PublicKey publicKey) {res = null;{

// Создаётся экземпляр кодировщика на основании алгоритма RSA.enc = Cipher.getInstance(ALGORITHM);

// Инициализация кодировщика открытым ключом..init(Cipher.ENCRYPT_MODE, publicKey);

// Шифровка сообщения за один проход.

res = new String(enc.doFinal(data.getBytes()));

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

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

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

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

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

}res;

}

.6.2 Метод decode() расшифрует предоставленные ему данные на основе сохранённого закрытого ключа. Описание метода представлено ниже:

/**

* @param data данные для расшифровки.

* @param privateKey закрытый ключ.

* @return расшифрованное сообщение.

*/static String decode(String data, PrivateKey privateKey) throws BadPaddingException {res = null;{

// Создаётся экземпляр кодировшика на основе алгоритма RSA.dec = Cipher.getInstance(ALGORITHM);

// Инициализация кодировщика закрытым ключом..init(Cipher.DECRYPT_MODE, privateKey);

// Расшифровка сообщения за один проход.

res = new String(dec.doFinal(data.getBytes()));

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

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

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

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

}res;

}

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

/**

* Метод генерирует пару ключей, необходимую для

* дешифровки входящих сообщений.

private void initKeys() {

if(internalKeyPair == null) {generator;{= KeyPairGenerator.getInstance(RSACipher.ALGORITHM);.initialize(512);= generator.generateKeyPair();

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

}

}

}

5 Тестирование программы

Чтобы запустить программу, на компьютере должна быть установлена JVM (виртуальная машина Java) версии 1.6.

Для запуска чата из консоли нудно написать следующую команду: java -jar путь_к_файлу_.jar.

После это должно появиться главное окно программы (рис. 5.1).

Рисунок 5.1 - Главное окно программы

Для проверки всех сетевых функций нужно запустить ещё один клиент программы на другом компьютеры в той же сети. После этого посредством передачи специальных пакетов (PRSN и SYNC), оба клиента синхронизируются. Результирующее отображение показано на рисунке 5.2, полученные пакеты на первом клиенте показаны на рисунке 5.3.

Рисунок 5.2 - Главное окно после входа ещё одного пользователя

Рисунок 5.3 - Полученные пакеты

Для смены ника нужно в поле с ником ввести новый ник и нажать клавишу Enter. После этого должно произойти обновление ник-нейма пользователя в обоих клиентах (рис. 5.4, 5.5).

Рисунок 5.4 - Отображение после обновления ника

Рисунок 5.5. - Полученные пакеты при смене Ника

Для проверки обычного взаимодействия пользователей через общий чат необходимо ввести в поле ввода сообщения первого клиента строку “hello :2:”, после чего проверить окно чата на другом клиенте (рис. 5.6, 5.7).

Рисунок 5.6 - Отображение при общении через общий чат

Рисунок 5.7 - Полученные пакеты при общении через общий чат

Для проверки установления защищённого соединения необходимо:

в окне первого клиента два раза щёлкнуть по нику того контакта, с кем нужно установить соединение (это второй клиент). После этого появится новая закладка с чатом и соединение будет установлено (рис. 5.8, 5.9, 5.10);

Рисунок 5.8 - Отображение при создании защищённого соединения

Рисунок 5.9 - Принимаемые пакеты при создании защищённого соединения со стороны первого клиента

Рисунок 5.10 - Принимаемые пакеты при создании защищённого соединения со стороны второго клиента

далее необходимо в первом клиенте ввести какое-либо сообщение (например, “java”), это сообщение должно отобразиться во втором клиенте (рис. 5.11, 5.12).

.11 - Отображение второго клиента при получении зашифрованного сообщения

программа шифрование соединение ник

.12 - Принятые пакеты при получении зашифрованного сообщения

Выводы

В ходе выполнения курсовой работы были освоены методы разработки программного обеспечения для создания UDP сокетов и протоколов. А также изучен методы асинхронного шифрования RSA.

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

 

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