Ответ
Модель OSI (Open Systems Interconnection) — это теоретическая 7-уровневая модель, описывающая, как данные передаются по сети. На практике стек TCP/IP (4 уровня) является ее реализацией. Уровни соотносятся по принципу инкапсуляции: данные с верхнего уровня становятся полезной нагрузкой (payload) для протокола нижнего уровня, который добавляет свой заголовок.
| Соответствие уровней OSI и TCP/IP: | Уровень OSI | Уровень TCP/IP | Пример протоколов | Задача | Пример в C++ (сокеты) |
|---|---|---|---|---|---|
| 7. Прикладной | Прикладной | HTTP, FTP, SMTP, DNS | Интерфейс для приложений | Библиотеки: cURL, gRPC, Boost.Asio для HTTP | |
| 6. Представления | (Включен в Прикладной) | SSL/TLS, JSON/XML parsers | Шифрование, сжатие, кодирование | OpenSSL для TLS, библиотеки сериализации | |
| 5. Сеансовый | (Включен в Прикладной) | SOCKS, RPC | Управление сеансом связи | Состояние соединения в клиент-серверном приложении | |
| 4. Транспортный | Транспортный | TCP, UDP | Надежная/ненадежная доставка данных между процессами | Создание сокета: socket(AF_INET, SOCK_STREAM, 0) (TCP) |
|
| 3. Сетевой | Интернет | IP (IPv4/IPv6), ICMP | Маршрутизация пакетов по сети | Заполнение структуры sockaddr_in (IP-адрес, порт) |
|
| 2. Канальный | Сетевой интерфейс | Ethernet (MAC), Wi-Fi (802.11) | Передача кадров между соседними узлами | Обычно управляется ОС и драйверами | |
| 1. Физический | (Аппаратный) | Витая пара, оптоволокно | Передача битов | Не программируется на уровне C++ |
Практический пример на C++ (сырые сокеты Беркли):
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <cstring>
int main() {
// Уровень 4 (Транспортный): Создаем TCP-сокет (SOCK_STREAM)
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
// Уровень 3 (Сетевой): Настраиваем адрес (IP и порт)
struct sockaddr_in address;
address.sin_family = AF_INET; // Семейство адресов IPv4
address.sin_addr.s_addr = INADDR_ANY; // Принимать соединения на все интерфейсы
address.sin_port = htons(8080); // Порт 8080 (преобразование в сетевой порядок байт)
// Связываем сокет с адресом (уровни 3 и 4)
bind(server_fd, (struct sockaddr*)&address, sizeof(address));
// Начинаем прослушивание (уровень 5, управление сеансом)
listen(server_fd, 3);
std::cout << "Server listening on port 8080..." << std::endl;
// Принимаем соединение
int addrlen = sizeof(address);
int new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen);
// Уровень 7 (Прикладной): Читаем и отправляем данные (простой HTTP-ответ)
const char* response =
"HTTP/1.1 200 OKrn"
"Content-Type: text/plainrn"
"Content-Length: 13rn"
"rn"
"Hello, OSI!n";
send(new_socket, response, strlen(response), 0);
close(new_socket);
close(server_fd);
return 0;
}
Современный подход на C++: Использование высокоуровневых библиотек, таких как Boost.Asio, которые абстрагируют низкоуровневые детали сокетов и предоставляют асинхронный ввод-вывод, упрощая работу с транспортным и сетевым уровнями.