Similar presentations:
Л 8 Сетевое программирование
1. Языки программирования
Лекция 8Сетевое программирование в Python
Зикратов Игорь Алексеевич, д.т.н., проф.
2026
2.
План лекции:1. Введение в сетевые протоколы и сокеты
2. Работа с TCP (Transmission Control Protocol)
3. Работа с UDP (User Datagram Protocol)
4. Асинхронное программирование (asyncio)
3.
1. Введение в сетевые протоколы и сокетыЧто такое сетевое программирование? Это обмен данными между
независимыми программами, которые могут работать на разных компьютерах.
Где применяется: веб-серверы, чаты, базы данных, IoT, распределенные
вычисления
Стек протоколов TCP/IP: Нас интересуют два основных
транспортных протокола:
o
TCP (Transmission Control Protocol): Протокол, ориентированный
на соединение. Гарантирует доставку, контролирует целостность и
порядок пакетов. Пример: HTTP, Email.
o
UDP (User Datagram Protocol): Протокол без установления
соединения. Отправка датаграмм. Нет гарантии доставки. Быстрее, но
ненадежнее. Пример: Видеозвонки, DNS, игры.
4.
Что такое сокет?Сокет (Socket) — это программный интерфейс ("дверь"),
через который программа отправляет и принимает данные.
Это абстракция конечной точки соединения.
Аналогия с телефонным звонком (для TCP):
o
Сервер: включает телефон (создает сокет), ждет звонка
(bind, listen).
o
Клиент: набирает номер (connect).
o
Сервер: снимает трубку (accept). Соединение
установлено.
o
Оба говорят (send/recv).
o
Один вешает трубку (close).
5.
o
o
o
TCP).
o
o
o
o
Основные функции сокетов:
socket() - создание сокета.
bind() - привязка к адресу и порту (обычно на сервере).
listen() - прослушивание входящих соединений (сервер
accept() - принятие входящего соединения (сервер TCP).
connect() - подключение к удаленному серверу (клиент).
send() / recv() - отправка и получение данных.
close() - закрытие сокета.
IP-адрес и Порт:
o
o
IP-адрес: идентификатор компьютера в сети.
Порт: идентификатор конкретного процесса на
компьютере (от 0 до 65535). Привилегированные
порты (0-1023) требуют прав администратора.
6.
2. Работа с TCP (Transmission Control Protocol)Разберем создание эхо-сервера: он получает сообщение и отправляет
его обратно клиенту.
1.
Импорт модуля: import socket
2. Создание сокета:
Для создания сокета используем метод socket(), передав два аргумента:
family: Тип адресации. Здесь мы используем AF_INET (самый распространенный),
что означает использование протокола IP версии 4 (IPv4).
type: Тип транспорта. Мы выбрали SOCK_STREAM, что соответствует протоколу TCP,
обеспечивающему надежное соединение с передачей потока байтов.
7.
3.Настройка опций (необязательно, но полезно): Позволяет
переиспользовать адрес и порт сразу после перезапуска сервера, избегая
ошибки "Address already in use".
4.
Привязка (Bind): Указываем, на каком IP и порту слушать. Пустой IP
('' или '0.0.0.0') означает "слушать на всех доступных сетевых
интерфейсах".
Здесь 127.0.0.1 — это локальный адрес (localhost), сервер будет доступен
только внутри вашего компьютера. 8888 — номер порта (можно выбрать
любой свободный от 1024 до 65535).
8.
5.Ожидание соединения (Listen): Превращает сокет в пассивный.
Сервер переходит в режим ожидания. В аргументе указывается
максимальное количество соединений в очереди.
6.
Цикл приема соединений (Accept): Когда клиент подключается,
метод accept() блокирует выполнение программы до появления
входящего запроса. Он возвращает новый объект сокета для общения с
конкретным клиентом и его адрес.
9.
7.Обмен данными с клиентом:
o
Получаем данные через recv().
o
buffer_size (например, 1024 байта) — сколько данных можно прочитать за
один раз.
o
Отправляем данные через sendall() (гарантирует отправку всех данных, в
отличие от send()).
Внимание! После завершения обмена данными важно
закрыть сокеты, чтобы освободить системные ресурсы.
10.
Еще один пример!11.
Создание TCP-клиентаВажно: Данные в сети передаются как
байты. Используем .encode() (в строку) и .decode() (из строки).
12.
Проблема последовательной обработки и пути решенияВ нашем примере сервер может обслуживать только одного клиента за раз.
Пока он общается с первым, второй висит в очереди.
Решение 1 (Мультипроцессорность): Принимаем клиента и запускаем
новый процесс Process(target=handle_client, args=(client_socket,)).
o
Плюсы: Изоляция, использование нескольких ядер CPU.
o
Минусы: Тяжеловесность.
o
o
Решение 2 (Мультипотоки): То же самое, но с потоками Thread.
Плюсы: Легче процессов, общая память.
Минусы: Сложность синхронизации.
Решение 3 (Асинхронность/Неблокирующие сокеты): Позволяет
обрабатывать тысячи соединений в одном потоке. Рассмотрим позже.
13.
3. Работа с UDP (User Datagram Protocol)Отличия UDP от TCP
Нет соединения: Не нужно вызывать connect() на клиенте и
listen()/accept() на сервере.
Нет гарантий: Пакеты могут теряться, дублироваться или приходить в
другом порядке.
Используется там, где важна скорость, а не надежность (стриминг,
игры).
14.
Пример UDP сервера и клиентаUDP-сервер:
1. Мы создаём объект типа socket, используя константу AF_INET, означающую
работу с IPv4, и SOCK_DGRAM, соответствующий протоколу UDP (User Datagram
Protocol). Это позволяет отправлять и получать пакеты данных без установки
постоянного соединения (в отличие от TCP). Адрес привязывается к локальному
хосту ('localhost'), и выбирается произвольный свободный порт (9999). Теперь этот
сокет ожидает входящих сообщений именно на данном адресе и порте.
2. Запуск бесконечного цикла прослушивания порта
Сервер находится в цикле ожидания поступления данных. Метод recvfrom()
принимает пакет размером максимум 1024 байта вместе с информацией об
источнике пакета (адрес клиента).
15.
3. Обработка полученных данныхСообщение преобразуется из бинарного формата в читаемый вид с
помощью метода .decode(), а затем выводится на экран с указанием
адреса отправителя. Далее строка превращается в верхний регистр
методом .upper().
4. Отправка ответа клиенту
Что произошло?
• Создали сокет и связали с адресом порта. Сервер запускается и ожидает запросов клиентов (бесконечный цикл
while).
• Когда клиент отправляет какое-то сообщение (например, команду), оно поступает на указанный порт (9999).
• Сообщение обрабатывается ( в нашем примере - преобразования всех символов в верхний регистр).
• Преобразованное сообщение отправляется обратно клиенту
16.
UDP-клиент:1. Здесь создается экземпляр класса socket, использующего семейство адресов
AF_INET (IPv4) и тип транспортного уровня SOCK_DGRAM (UDP). Это позволит нам
отправлять короткие UDP-пакеты на удалённые узлы. Определение адреса
сервера:
2. Попытка отправить сообщение
Клиент создаёт сообщение "Привет, UDP!", которое затем
конвертируется в двоичный формат с помощью метода .encode().
Затем эта закодированная версия отправляется серверу по
указанному адресу с помощью метода sendto().
17.
3. Ожидание ответа от сервераМетод recvfrom() позволяет принять ответ от сервера, ожидая максимальный
размер пакета в 1024 байта. Возвращаются полученные данные и информация о
сервере, с которого пришло сообщение.
4. Печать полученного ответа
Принимаемые данные расшифровываются с помощью метода .decode() и
выводятся на экран.
5. Закрытие сокета
Независимо от результата обработки, сокет закрывается
оператором close(), освобождая занятые системой ресурсы.
18.
Полная запись скрипта:Программа состоит из трёх ключевых этапов:
1. Отправка сообщения: Клиент формирует сообщение и отправляет его серверу по заданному адресу
и порту.
2. Ожидание ответа: Клиент ждёт ответ от сервера, принимая пакет размером до 1024 байт.
3. Обработка ответа: Если сервер отправил какой-либо ответ, клиент выводит его на экран.
19.
4. Асинхронное программирование (asyncio)Проблема потоков
Тысячи потоков создать нельзя (накладные расходы).
asyncio позволяет писать конкурентный код в одном потоке,
используя кооперативную многозадачность. Пока одна задача ждет
данных (например, recv), управление передается другой задаче.
Ключевые слова: async (определение корутины) и await
(ожидание результата долгой операции, не блокируя поток).
20.
Асинхронный эхо-серверhandle_client — обработка отдельных сессий клиентов:
reader/writer: Параметры reader и writer используются для чтения и записи данных
в потоки. Они передаются автоматически библиотекой asyncio, когда новое
подключение установлено.
await reader.read(1024): Код пытается
прочитать до 1024 байт данных от клиента.
Операция является асинхронной, поэтому
процесс приостановлен до завершения чтения
данных.
Если прочитанных данных нет (not data), значит
клиент завершил сеанс, и цикл прерывается.
writer.write(data): Данные, полученные от клиента, отправляются
обратно ему же (эффект эха). Метод write() записывает данные в
буфер, но фактическое отправление произойдёт позже. await
writer.drain(): Эта операция гарантирует, что записанные ранее
данные будут физически переданы клиенту. Без неё приложение
могло бы зависнуть из-за заполнения буфера записи.
Закрытие соединения: После окончания работы с данным клиентом
осуществляется закрытие объекта writer, гарантирующее корректное
завершение сеанса.
21.
Основной обработчик сервера — main:start_server: Эта функция запускает сервер на указанном
интерфейсе ('localhost') и порту (8888). Каждый новый
клиент получает свою собственную задачу (Task),
которую исполняет асинхронно, не мешая другим
подключениям.
addr = server.sockets[0].getsockname(): Адрес
активного сокета извлекается из массива сокетов
сервера, и он отображается в консоли для
информирования администратора о месте
запуска сервера.
Эта конструкция проверяет, запущен ли файл
непосредственно, а не импортирован извне.
Если условие истинно, запускается основной
цикл событий asyncio.run(main()), позволяющий
начать выполнение функций, отмеченных
ключевым словом async.
async with server: Используется менеджер
контекста для автоматического закрытия
сервера при выходе из блока.
serve_forever: Данная команда
приказывает серверу ожидать новых
подключений постоянно, пока явно не
остановят программу.
22.
Асинхронный клиент23.
ИТОГИ:o
Всегда закрывайте сокеты (лучше использовать контекстные менеджеры with).
o
Указывайте таймауты (socket.settimeout()) для операций, чтобы программа не
зависала.
o
Используйте sendall() вместо send() для TCP.
o
Что еще есть в сетевом программировании?
o
HTTP: Библиотеки http.server (базовый), requests (клиент), aiohttp
(асинхронный клиент/сервер).
o
WebSockets: Библиотека websockets для real-time приложений (чаты,
уведомления).
o
Высокоуровневые фреймворки: FastAPI (асинхронный), Django, Flask.
o
internet