- Создать простой эхо-сервер и клиент для него.
- Модифицировать код сервера таким образом, чтобы при подключении нового клиента создавался новый поток и вся работа с клиентом выполнялась в нем.
- Проверить возможность подключения нескольких клиентов к этому серверу одновременно.
Создан файл server.py, который позволяет серверу обрабатывать несколько подключений одновременно с использованием модуля threading.
- При каждом новом подключении создается отдельный поток для обработки клиента.
- Сервер фиксирует количество активных подключений.
Создан файл client.py, который подключается к серверу и обменивается сообщениями.
Пробуем подключиться к серверу с трёх клиентов:
Отключение клиента от сервера:
- Реализовать сканер TCP-портов. Программа должна запрашивать имя хоста/IP-адрес у пользователя. Затем программа должна пробовать подключиться к этому хосту ко всем портами по очереди. При успешном подключении программа должна выводить в консоль сообщение “Порт N открыт”.
- Модифицировать эту программу, чтобы сканирование портов происходило параллельно. Для этого нужно распараллелить сканирование портов по нескольким потокам.
- Обеспечить вывод списка открытых портов по порядку.
- Реализовать progress bar в командной строке, показывающий прогресс сканирования.
Создан файл port_scanner.py, который по заданному пользователем имени хоста/IP-адресу, выводит открытые порты.
Запустим сканнер портов на двух адресах. На втором после 443 программа была прервана вручную:
Модифицируем файл port_scanner.py, чтобы сканирование портов происходило параллельно, список открытых портов выводился по порядку, а прогресс сканирования отображался в командной строке в формате progress bar. Модифицированный код запишем в новый файл port_scanner_modified.py:
Было создано виртуальное окружение для загрузки дополнительного пакета:
python3 -m venv venv
source venv/bin/activateЗапустим модифицированный сканнер. Так отображается progress bar в процессе работы программы:
Вывод после полной отработки программы:
- Почему однопоточное приложение не может решить задачу одновременного подключения? В однопоточном приложении одна операция блокирует выполнение остальных, например, ожидание подключения или обработка данных. Многопоточность позволяет выполнять несколько операций параллельно.
- Чем поток отличается от процесса?
- Поток — это легковесный объект, разделяющий память с другими потоками в процессе.
- Процесс имеет собственное пространство памяти, что делает его более изолированным, но требующим больше ресурсов.
- Как создать новый поток?
Новый поток создается с помощью
threading.Thread. thread = threading.Thread(target=func, args=(arg1, arg2)) thread.start() - Как выделить участок кода так, чтобы он выполнялся в другом потоке?
Указать функцию в параметре
targetпри создании объектаThread. - В чем проблема потокобезопасности? Потоки могут одновременно изменять общие данные, что приводит к несогласованности состояния.
- Какие методы обеспечения потокобезопасности существуют?
- Использование блокировок (
threading.Lock). - Мьютексы, семафоры.
- Queue для безопасного обмена данными между потоками.
- Использование блокировок (










