
Лекции, Кокарева, TR_TKC / 7. Распределённые приложения. Архитектура клиент-сервер
..docx
Распределённые
приложения. Архитектура клиент-сервер
Лекция
7 по дисциплине: Технологии разработки
телекоммуникационных сервисов
ФГОБУ
ВПО СибГУТИ
February
25, 2014
Автор:
Е.В. Кокорева
-
ОБЩИЕ СВЕДЕНИЯ
-
Распределённое приложение
-
Распределённое приложение – это программа, состоящая из нескольких взаимодействующих частей, каждая из которых, как правило, выполняется на отдельном компьютере (или другом устройстве) сети.
-
Распределённая система
Распределённая система – программно-аппаратное решение, состоящее из компонентов, функционирующих на физически удаленных и независимых друг от друга гетерогенных узлах, представляющееся пользователям единой объединенной системой.
Свойства Распределённых систем:
-
управляемость - способность системы эффективно контролировать свои составные части;
-
производительность - обеспечивается за счет возможности перераспределения нагрузки на серверы системы с помощью управляющего ПО;
-
масштабируемость - при необходимости физического повышения производительности распределенная система может легко интегрировать в своей транспортной среде новые вычислительные ресурсы;
-
расширяемость - к распределенным приложениям можно добавлять новые составные части (серверное ПО) с новыми функциями.
Недостатки распределённых систем:
-
коммуникационная среда – слабое место распределённых систем, поэтому ошибки в таких системах возникают чаще, чем в монолитных;
-
архитектура распределённого приложения сложнее, чем монолитного.
Требования к распределённым системам:
-
использование открытых стандартов для обеспечения независимости от конкретной платформы и работы программных систем в гетерогенной среде;
-
безопасность, включает в себя:
-
конфиденциальность,
-
целостность,
-
доступность;
-
-
обеспечение качества обслуживания (QoS) в сети.
-
Архитектура клиент-сервер
-
РЕАЛИЗАЦИЯ КЛИЕНТ-СЕРВЕРНОЙ АРХИТЕКТУРЫ НА СОКЕТАХ
Со́кет (англ. socket — углубление, гнездо, разъём) — название программного интерфейса для обеспечения обмена данными между процессами на одном устройстве или на различных, связанных между собой сетью.
Следует различать клиентские и серверные сокеты.
Клиентское приложение (например, браузер) использует только клиентские сокеты, а серверное (например, веб-сервер, которому браузер посылает запросы) — как клиентские, так и серверные сокеты.
Для создания сокета необходимо, во-первых определить стиль взаимодействия сетевых объектов (процессов).
Стиль взаимодействия может быть основан на:
-
TCP (Transmission Control Protocol) - надежное соединение;
-
UDP (User Datagram Protocol) - ненадежное соединение (датаграммный метод передачи).
Во-вторых, необходимо задать адрес сокета, который идентифицирует один конец подключения сокета.
Адрес сокета состоит из:
-
IP-адреса сервера,
-
номера порта, который идентифицирует сокет (процесс) среди множества сокетов (процессов) на сервере (порты с 1 по 1024 зарезервированы операционной системой).
-
Организация обмена
В общих чертах последовательность действий:
-
на стороне клиента:
-
создание клиентского сокета;
-
установка параметров сокета (IP-адрес и порт, к которым необходимо подключиться);
-
установка соединения между сокетом и удаленной конечной точкой;
-
отправка/получение информации;
-
разрыв соединения и освобождение сокета.
-
-
на стороне сервера:
-
создание серверного сокета;
-
установка параметров серверного сокета (IP-адрес и порт, на которые ожидаются подключения);
-
перевод серверного сокета в режим отслеживания входящих соединений;
-
при наличии входящего соединения: получить отдельный сокет для работы с этим конкретным соединением;
-
отправка/получение информации;
-
по окончании работы с клиентом: разрыв соединения и освобождение сокета, привязанного к этому клиенту;
-
по окончании работы сервера: освобождение серверного сокета.
-
3.2. Использование API java.net
Для организации обмена информацией через сокеты в пакете java.net определены классы протокола UDP и TCP.
-
Сокет UDP
Для работы с UDP в пакете java.net определены следующие классы.
1. DatagramSocket предназначен для посылки/приема UDP дейтаграмм.
Конструкторы класса:
-
DatagramSocket() создаваемый сокет присоединяется к любому свободному порту на хосте;
-
DatagramSocket(int port) создаваемый сокет присоединяется к порту port на хосте;
-
DatagramSocket(int port, InetAddress addr) создаваемый сокет присоединяется к порту port; аргумент addr – IP-адрес сервера.
Методы класса:
-
send(DatagramPacket pack) — отправляет дейтаграмму, упакованную в пакет pack;
-
receive(DatagramPacket pack) — дожидается получения дейтаграммы и заносит ее в пакет pack;
-
setSoTimeout() устанавливает тайм-аут для операций сокета;
-
close() — закрывает сокет.
2. DatagramPacket предназначен для представления единичной дейтаграммы.
функция приема (receive()) возвращает экземпляр этого класса.
Конструкторы класса:
-
DatagramPacket(byte[] buf, int length) служит для получения пакета длиной length, buf буфер для получения дейтаграммы;
-
DatagramPacket(byte[] buf, int length, InetAddress addr, int port) создаёт пакет дейтаграммы длиной length, чтобы отправить его к указанному номеру порта (port) на указанном узле (address), buf буфер, содержащий данные для передачи.
Вспомогательные методы:
-
connect(InetAddress addr, int port) установить соединение;
-
disconnect() разъединить;
-
InetAddress.getByName(host) получить IP-адрес хоста;
Пример:
InetAddress aHost =
InetAddress.getByName("www.dom.ru");
Если клиент и сервер запущены на одном хосте используется адрес "127.0.0.1" или "localhost"
-
Пример UDP клиента:
Приведённая в примере программа создает сокет, соединяется с сервером (порт 2100), пересылает ему сообщение и ждет ответа:
import java.net.*; // подключение библиотек
import java.io.*;
public class UDPClient{
public static void main(String args[]){
try {
// создаём сокет
DatagramSocket aSocket = new DatagramSocket();
// задаём строку для передачи
String str = "Hello";
// и преобразуем её в поток байт
byte [] message = str.getBytes();
// получаем IP-адрес компьютера в формате Java
InetAddress aHost =
InetAddress.getByName("localhost");
// задаём порт
int sPort = 2100;
// создаём дейтаграмму, длина которой
// определяется длиной сообщения
DatagramPacket request =
new DatagramPacket(message, message.length, aHost, sPort);
// передаём серверу
aSocket.send(request);
// определяем буфер под ответ сервера
byte [] buffer = new byte[1000];
// создаём дейтаграмму под ответ сервера
DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
// принимаем ответ
aSocket.receive(reply);
// выводим ответ на консоль
System.out.println("Reply: " + new String(reply.getData()));
// после чего закрываем сокет
aSocket.close();
// если не получилось создать сокет
} catch (SocketException e){
System.out.println("Socket: " + e.getMessage());
// ошибка при приеме
} catch (IOException e){System.out.println("IO: " + e.getMessage());
} // конец try…catch
} // конец метода
} // конец класса
Пример UDP сервера:
Метод main() класса UDPServer создает сокет, принимает запрос клиента и возвращает клиенту полученное от него текстовое сообщение
import java.net.*;
import java.io.*;
public class UDPServer{
public static void main(String args[]) {
DatagramSocket aSocket = null;
try{
// создаём сокет: порт 2100
aSocket = new DatagramSocket(2100);
// резервируем буфер под клиентское сообщение
byte [] buffer = new byte[1000];
while(true){ // бесконечный цикл
// резервируем дейтаграмму под пакет клиента
DatagramPacket request =
new DatagramPacket(buffer, buffer.length);
// принимаем пакет клиента
aSocket.receive(request);
// создаём ответную дейтаграмму
DatagramPacket reply =
new DatagramPacket(request.getData(),
request.getLength(), request.getAddress(), request.getPort());
// отправляем ответ клиенту
aSocket.send(reply);
}
// обрабатываем ошибку создания сокета
} catch (SocketException e) {
System.out.println("Socket: " +
e.getMessage());
// обрабатываем ошибку передачи пакета
} catch (IOException e) {
System.out.println("IO: " + e.getMessage());
} finally {
// закрываем сокет
if(aSocket != null) aSocket.close();
}
} // конец метода
} // конец класса
-
Сокет TCP
Классы:
1. Socket
Конструктор:
Socket(InetAddress host, int serverPort) – создаёт клиентский сокет, аргументы IP-адрес сервера и порт;
Пример:
InetAddress ipAddress =
InetAddress.getByName("127.0.0.1");
Socket socket = new Socket(ipAddress,2222);
2. ServerSocket
Конструктор:
ServerSocket(int serverPort) – служит для создания «слушающего» сокета на сервере.
Метод:
accept() – ожидание сервером нового соединения.
Пример (на стороне сервера):
ServerSocket servsock = new ServerSocket(7896);
Socket sock = servsock.accept();
Первая строка примера создаёт «слушающий» сокет сервера (ожидающий клиента). Во второй строке метод accept() серверного сокета (servsock) возвращает соответствующий сокет (sock) для общения с клиентом.
После сеанса связи сокеты следует закрыть, используя метод close().
Для передачи данных используются методы потокового ввода/вывода и сериализации, рассмотренные в лекции №5.