272.56K
Категория: ИнтернетИнтернет

ИСРПО. Транспортные протоколы для взаимодействия программных модулей

1.

ИСРПО
Транспортные протоколы для
взаимодействия программных
модулей

2.

Транспортный уровень OSI
Транспортный уровень – обеспечивает
приложениям или верхним уровням стека –
прикладному, представления и сеансовому –
передачу данных с той степенью надежности,
которая им требуется. Модель OSI определяет пять
классов транспортного сервиса от низшего класса 0
до высшего класса 4. Эти виды сервиса отличаются
качеством предоставляемых услуг: срочностью,
возможностью восстановления прерванной связи,
наличием средств мультиплексирования нескольких
соединений между различными прикладными
протоколами через общий транспортный протокол,
а главное – способностью к обнаружению и
исправлению ошибок передачи, таких как
искажение, потеря и дублирование пакетов.

3.

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

4.

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

5.

Транспортный уровень OSI
Функции транспортного уровня:
преобразование транспортного адреса в сетевой;
межоконечное мультиплексирование транспортных
соединений в сетевые;
установление и разрыв транспортных соединений;
межоконечное упорядочение блоков данных по отдельным
соединениям;
межоконечное обнаружение ошибок и необходимый контроль
качества услуг;
межоконечное восстановление после ошибок;
межоконечное сегментирование, объединение и сцепление;
межоконечное управление потоком данных по отдельным
соединениям;
супервизорные функции;
передача срочных транспортных сервисных блоков данных.

6.

Транспортный уровень OSI
Транспортный уровень стека TCP/IP
может предоставлять вышележащему уровню
два типа сервиса:
• гарантированную доставку обеспечивает
протокол управления передачей
(Transmission Control Protocol, TCP);
• доставку по возможности, или с
максимальными усилиями, обеспечивает
протокол пользовательских дейтаграмм
(User Datagram Protocol, UDP).

7.

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

8.

Мультиплексирование и
демультиплексирование
Существует и обратная задача: пакеты,
которые отправляют в сеть разные
приложения, работающие на одном
конечном узле, обрабатываются общим для
них протоколом IP. Следовательно, в стеке
должно быть предусмотрено средство
«сбора» пакетов от разных приложений для
передачи протоколу IP. Эту работу
выполняют протоколы TCP и UDP.

9.

Мультиплексирование и
демультиплексирование
• Процедура приема данных
протоколами TCP и UDP,
поступающих от нескольких
различных прикладных служб,
называется
мультиплексированием.
• Обратная процедура – процедура
распределения протоколами TCP
и UDP поступающих от сетевого
уровня пакетов между набором
высокоуровневых служб –
называется
демультиплексированием

10.

Мультиплексирование и
демультиплексирование
Протоколы TCP и UDP ведут для каждого
приложения две очереди:
• очередь пакетов, поступающих к данному приложению
из сети;
• очередь пакетов, отправляемых данным приложением
в сеть.
Пакеты, поступающие на транспортный уровень,
организуются операционной системой в виде множества
очередей к точкам входа различных прикладных
процессов. В терминологии TCP/IP такие системные
очереди называются портами, причем входная и
выходная очереди одного приложения рассматриваются
как один порт. Для однозначной идентификации портов
им присваивают номера. Номера портов используются для
адресации приложений.

11.

Протокол UDP
Протокол UDP, являясь дейтаграммным
протоколом, реализует сервис по
возможности, то есть не гарантирует
доставку своих сообщений, а,
следовательно, никоим образом не
компенсирует ненадежность
дейтаграммного протокола IP.
Единица данных протокола UDP
называется UDP-пакетом или
пользовательской дейтаграммой (user
datagram).

12.

Протокол UDP
Каждая дейтаграмма переносит отдельное
пользовательское сообщение. Это приводит к
естественному ограничению: длина
дейтаграммы UDP не может превышать длины
поля данных протокола IP, которое, в свою
очередь, ограничено размером кадра
технологии нижнего уровня.
Поэтому если UDP-буфер переполняется, то
данные приложения отбрасываются.
Заголовок UDP-пакета, состоящий из четырех
2-байтовых полей, содержит поля порт
источника, порт получателя, длина UDP и
контрольная сумма.

13.

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

14.

Протокол TCP
Протокол TCP (Transmission Control Protocol) обеспечивает
надежную транспортировку данных между прикладными
процессами путем установления логического соединения.
Установление соединения происходит в три шага:
1. Клиент, запрашивающий соединение, отправляет серверу
пакет, указывающий номер порта, который клиент желает
использовать, а также код (определенное число) ISN (Initial
Sequence number).
2. Сервер отвечает пакетом, содержащим ISN сервера, а также
ISN клиента, увеличенный на 1.
3. Клиент должен подтвердить установление соединения,
вернув ISN сервера, увеличенный на 1.
Трехступенчатое открытие соединения устанавливает
номер порта, а также ISN клиента и сервера. Каждый
отправляемый TCP – пакет содержит номера TCP – портов
отправителя и получателя, номер фрагмента для сообщений,
разбитых на меньшие части, а также контрольную сумму,
позволяющую убедиться, что при передаче не произошло ошибок.

15.

Протокол TCP
Информация, поступающая к протоколу TCP от протоколов
более высокого уровня, рассматривается протоколом TCP как
неструктурированный поток байтов.
Поступающие данные буферизируются средствами TCP.
Для передачи на сетевой уровень из буфера «вырезается»
некоторая непрерывная часть данных, которая называется
сегментом.
Сегмент состоит из фиксированного 20-байтного заголовка
(плюс необязательная часть), за которой могут следовать байты
данных. Размер сегментов определяется программным
обеспечением TCP. Оно может объединять в один сегмент
данные, полученные в результате нескольких операций записи,
или, наоборот, распределять результаты одной записи между
несколькими сегментами.

16.

Протокол TCP
Размер сегментов ограничен двумя
пределами. Во-первых, каждый сегмент,
включая TCP-заголовок, должен помещаться в
65 515-байтное поле полезной нагрузки IPпакета. Во-вторых, в каждой сети есть
максимальная единица передачи (MTU,
Maximum Transfer Unit), и каждый сегмент
должен помещаться в MTU. На практике
размер максимальной единицы передачи
составляет обычно 1500 байт (что
соответствует размеру поля полезной нагрузки
Ethernet), и таким образом определяется
верхний предел размера сегмента.

17.

Формат TCP-пакета
Формат заголовка сегмента TCP
Структура пакета TCP при вычислении
контрольной суммы
Структура псевдозаголовка пакета TCP
Заголовок TCP-сегмента содержит
значительно больше полей, чем заголовок
UDP, что отражает более развитые
возможности первого протокола.

18.

Сессии TCP
Основным отличием TCP от UDP является то, что на протокол TCP
возложена дополнительная задача – обеспечить надежную доставку
сообщений, используя в качестве основы ненадежный
дейтаграммный протокол IP.
Установленные на конечных узлах протокольные модули TCP
решают задачу обеспечения надежного обмена данными путем
установления между собой логических соединений. Благодаря
логическому соединению TCP следит, чтобы передаваемые сегменты
не были потеряны, не были продублированы и пришли к получателю
в том порядке, в котором были отправлены.
При установлении логического соединения модули TCP
договариваются между собой о параметрах процедуры обмена
данными. В протоколе TCP каждая сторона соединения посылает
противоположной стороне следующие параметры:
• максимальный размер сегмента, который она готова принять;
• максимальный объем данных (возможно несколько сегментов),
которые она разрешает другой стороне передавать в свою сторону.
Даже если та еще не получила квитанцию на предыдущую порцию
данных (размер окна);
• начальный порядковый номер байта, с которого она начинает отсчет
потока данных в рамках данного соединения.

19.

Сессии TCP
Чтобы установить соединение,
одна сторона (например, сервер)
пассивно ожидает входящего
соединения, выполняя
примитивы LISTEN (объявление о
желании принять соединение) и
ACCEPT (блокирование
звонящего до получения
попытки соединения), либо
указывая конкретный источник,
либо не указывая его.
Другая сторона (например,
клиент) выполняет примитив
CONNECT (активно пытаться
установить соединение),
указывая IP-адрес и порт, с
которым он хочет установить
соединение, максимальный
размер TCP-сегмента и, по
желанию, некоторые данные
пользователя (например,
пароль) Примитив CONNECT
посылает TCP-сегмент с
установленным битом SYN и
сброшенным битом ACK и ждет
ответа.
Когда этот сегмент прибывает в пункт
назначения, TCP-сущность проверяет, выполнил
ли какой-нибудь процесс примитив LISTEN,
указав в качестве параметра тот же порт,
который содержится в поле порт получателя.
Если такого процесса нет, она отвечает
отправкой сегмента с установленным битом
RST для отказа от соединения.

20.

Реализация обмена данными по
сети
Обмен данных по сети – это процесс передачи
информации между устройствами через сетевое
соединение. Этот процесс может быть разделен на
несколько этапов:
1. Установление соединения
- Для начала обмена данных необходимо установить
соединение между отправителем и получателем.
Обычно это происходит посредством протокола TCP или
UDP.
- При использовании TCP процесс установления
соединения включает в себя установку трехстороннего
рукопожатия (three-way handshake) между
отправителем и получателем, чтобы обе стороны
подтвердили готовность к обмену данными.

21.

Реализация обмена данными по
сети
2. Передача данных
- После установления соединения данные могут быть
переданы от отправителя к получателю. Данные могут
быть переданы как в виде потока байтов, так и в виде
пакетов данных (датаграмм) в зависимости от
используемого протокола (TCP или UDP).
- При использовании TCP данные передаются с учетом
порядка и доставки, что гарантирует надежность
передачи. В случае UDP передача данных может быть
более быстрой, но менее надежной.
3. Обработка данных
- Полученные данные могут быть обработаны
получателем в соответствии с логикой приложения.
Может включать в себя разбор и анализ данных,
выполнение необходимых операций и принятие
решений на основе полученной информации.

22.

Реализация обмена данными по
сети
4. Завершение соединения
- По завершении передачи данных соединение
может быть закрыто. В случае использования TCP
это может включать в себя установление
специального флага FIN для завершения
соединения и обмена подтверждениями.
5. Обработка ошибок и восстановление соединения
- В процессе обмена данных по сети могут возникать
различные ошибки, такие как потеря пакетов,
задержки или недоступность получателя. Для
обеспечения надежности передачи данных могут
использоваться механизмы обработки ошибок,
повторной отправки данных и восстановления
соединения.

23.

Сокеты
Сокеты являются основным механизмом для
обмена данных между устройствами через сеть в
программировании. Они представляют собой точку
входа в сетевое соединение и позволяют
устанавливать связь между клиентом и сервером.
Типы сокетов:
- Пассивные сокеты (слушающие). Обычно
используются серверами для прослушивания
входящих соединений. Они ожидают запросов на
подключение от клиентов.
- Активные сокеты (клиентские). Используются
клиентами для установления соединения с
сервером. Они инициируют соединение с
сервером.

24.

Сокеты
Сокеты могут быть созданы для различных
доменов (например, AF_INET для IPv4, AF_INET6 для
IPv6) и протоколов (например, SOCK_STREAM для
TCP, SOCK_DGRAM для UDP). Например, для
создания TCP-сокета в домене IPv4 можно
использовать комбинацию AF_INET и SOCK_STREAM.
Для создания сокета в языке программирования,
C++ или Python, используются специальные
функции или классы из сетевых библиотек
(например, socket() в C++ или socket.socket() в
Python). После создания сокета его нужно привязать
к определенному адресу и порту. Это позволяет
определить, через какой адрес и порт будет
происходить обмен данных.

25.

Сокеты
Для активных сокетов (клиентских)
необходимо установить соединение с
сервером, отправив запрос на соединение.
Для пассивных сокетов (слушающих)
необходимо прослушивать входящие
соединения и принимать их при поступлении
запросов. После установления соединения
данные могут быть переданы через сокет с
использованием методов отправки и приема
данных (например, send() и recv() в C++). По
завершении обмена данными сокет должен
быть корректно закрыт для освобождения
ресурсов и завершения соединения.

26.

Сокеты
Основные системные вызовы для работы с сокетами:
• socket — создание сокета
• connect — инициация клиентского соединения
• bind — привязка сокета к порту
• listen — перевод сокета в пассивный режим прослушивания
порта (актуально только для TCP соединений)
• accept — принятие соединения от клиента (который вызвал
операцию connect) — это блокирующая операция, которая ждет
поступления нового соединения
• read/write или же send/recv — запись/чтение данных в сокет
• recvfrom/sendto — аналогичные операции для UDP сокетов
• setsockopt — установка параметров сокета
• close — закрытие сокета

27.

Сокеты
Поскольку сокеты — это, фактически, интерфейс для погружения
на третий уровень TCP/IP-стека, сокеты не предоставляют механизмов
для управления кодированием данных и сеансами работы
приложений — они просто позволяют передать "сырой" поток байт.
Общая схема взаимодействия через сокет:

28.

Сокеты
Как видно из схемы, на сервере для установления
TCP соединения нужно выполнить 3 операции:
• bind захватывает порт, после чего другие процессы не
смогут занять его для себя
• listen (для TCP соединения) переводит его в режим
прослушивания, после чего клиенты могут
инициировать подключения к нему
• пока на сервере не выполнен accept, клиентские
соединения будут ожидать в очереди (backlog) сокета,
ограничения на которую могут быть заданы в вызове
listen
Выполнение accept приводит к появлению еще
одного объекта сокета, который отвечает текущему
клиентскому соединению. При этом серверный сокет
может принимать новые соединения.

29.

Пример сервера
#include <iostream>
#include <winsock2.h> //winsock2.h содержит определения для работы с сетевыми сокетами в Windows.
#pragma comment(lib, "ws2_32.lib“)
// Директива препроцессора, указывающая компилятору ассоциировать программу с библиотекой ws2_32.lib,
//необходимой для работы с сокетами в Winsock.
int main() {
WSADATA wsaData; // Создание переменной wsaData типа WSADATA, которая будет использоваться для хранения информации о инициализации Winsock.
WORD DLLVersion = MAKEWORD(2, 1); // Создание переменной DLLVersion типа WORD, которая содержит версию Winsock, в данном случае 2.1.
if (WSAStartup(DLLVersion, &wsaData) != 0) {
// Вызов функции WSAStartup() для инициализации библиотеки Winsock с указанной версией и сохранением информации в
std::cout << "Error initializing Winsock!" << std::endl; // переменной wsaData. Если инициализация не удалась, выводится сообщение об ошибке.
return 1;
}
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0); // Создание сокета сервера с помощью функции socket(). Параметры AF_INET (IPv4), SOCK_STREAM (TCP) и 0 (протокол
//по умолчанию).
if (serverSocket == INVALID_SOCKET) { // Проверка на ошибку при создании сокета. Если сокет не был создан успешно, выводится сообщение об ошибке.
std::cout << "Error creating socket!" << std::endl;
return 1;
}
SOCKADDR_IN serverAddr; // Создание структуры SOCKADDR_IN для хранения информации об адресе и порте сервера.
serverAddr.sin_addr.s_addr = INADDR_ANY; // Установка IP-адреса сервера на все доступные интерфейсы.
serverAddr.sin_family = AF_INET; // Установка семейства адресов (IPv4).
serverAddr.sin_port = htons(1111); // Установка порта сервера в порядке байт сети TCP/IP (htons() преобразует порт в правильный формат).
if (bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { // Привязка сокета к определенному адресу и порту с помощью функции bind(). Если
std::cout << "Error binding socket!" << std::endl;
// привязка не удалась, выводится сообщение об ошибке.
return 1;
}
listen(serverSocket, SOMAXCONN); // Перевод сокета в режим прослушивания входящих соединений (указывается максимальная длина очереди соединений).
std::cout << "Server is listening..." << std::endl; // Вывод сообщения о том, что сервер прослушивает соединения.
SOCKADDR_IN clientAddr; // Создание структуры SOCKADDR_IN`для хранения информации об адресе и порте клиента.
int sizeofClient = sizeof(clientAddr); // Получение размера clientAddr
SOCKET clientSocket = accept(serverSocket, (SOCKADDR*)&clientAddr, &sizeofClient); // Принятие входящего соединения с клиентом с помощью функции accept(). Создается новый
//сокет для общения с клиентом.
std::cout << "Client connected!" << std::endl; // Вывод сообщения о том, что клиент подключился.
char buffer[256]; // Создание буфера для приема данных от клиента
recv(clientSocket, buffer, sizeof(buffer), 0); // Получение данных от клиента с помощью функции recv() и сохранение их в буфере.
std::cout << "Received data: " << buffer << std::endl; // Вывод данных, полученных от клиента.
closesocket(clientSocket); // Закрытие сокета клиента после завершения обмена данными
closesocket(serverSocket); // Закрытие сокета сервера
WSACleanup(); // Освобождение ресурсов Winsock после завершения работы с сокетами.
return 0;
}

30.

Пример клиента
#include <iostream>
#include <winsock2.h> //winsock2.h содержит определения для работы с сетевыми сокетами в Windows.
#pragma comment(lib, "ws2_32.lib") // Директива препроцессора, указывающая компилятору ассоциировать программу с библиотекой ws2_32.lib,
//необходимой для работы с сокетами в Winsock.
int main() {
WSADATA wsaData; // Создание переменной wsaData типа WSADATA, которая будет использоваться для хранения информации о
//инициализации Winsock.
WORD DLLVersion = MAKEWORD(2, 1); // Создание переменной DLLVersion типа WORD, которая содержит версию Winsock, в данном случае 2.1.
if (WSAStartup(DLLVersion, &wsaData) != 0) {
// Вызов функции `WSAStartup()` для инициализации библиотеки Winsock с указанной
std::cout << "Error initializing Winsock!" << std::endl; // версией и сохранением информации в переменной `wsaData`. Если инициализация не
return 1;
// удалась, выводится сообщение об ошибке.
}
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0); // Создание сокета клиента с помощью функции socket(). Параметры AF_INET (IPv4),
// SOCK_STREAM (TCP) и 0 (протокол по умолчанию).
if (clientSocket == INVALID_SOCKET) {
// Проверка на ошибку при создании сокета. Если сокет не был создан успешно,
std::cout << "Error creating socket!" << std::endl;
// выводится сообщение об ошибке.
return 1;
}
SOCKADDR_IN serverAddr; // хранение информации об адресе и порте сервера.
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Установка IP-адреса сервера (в данном случае localhost)
serverAddr.sin_family = AF_INET; // Установка семейства адресов (IPv4).
serverAddr.sin_port = htons(1111); // Установка порта сервера в порядке байт сети TCP/IP (htons() преобразует порт в правильный формат).
if (connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { //Установление соединения с сервером с помощью
std::cout << "Error connecting to server!" << std::endl;
// функции `connect()`. Если соединение не удалось,
return 1;
// выводится сообщение об ошибке.
}
char message[256] = "Hello from client!"; //Создание сообщения, которое будет отправлено серверу
send(clientSocket, message, sizeof(message), 0); //Отправка сообщения серверу с помощью функции send()
closesocket(clientSocket); //Закрытие сокета клиента после завершения обмена данными
WSACleanup(); //Освобождение ресурсов Winsock после завершения работы с сокетами.
return 0;
}
English     Русский Правила