Files
hse-2026/materials/04-group-comm/seminar/ip_multicast/readme.md
T
2026-10-01 22:08:30 +03:00

71 lines
4.7 KiB
Markdown

# IP multicast
Один контейнер принимает UDP-датаграммы на порту 9999 и пересылает их на multicast-адрес `224.0.2.0:10000`. Три контейнера-получателя присоединяются к этой группе и печатают полученные сообщения. В примере нет подтверждений, повторной передачи и восстановления пропусков.
## Запуск
Из корня репозитория перейдите в каталог примера и запустите контейнеры:
```sh
cd materials/04-group-comm/seminar/ip_multicast
docker compose up --build -d
docker compose logs -f sender receiver1 receiver2 receiver3
```
Дождитесь сообщения `ready` от отправителя и каждого получателя. Последняя команда показывает журналы и занимает терминал. Следующие команды выполняйте во втором терминале из того же каталога.
Отправьте пробное сообщение через Python 3:
```sh
python -c "import socket; s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.sendto(b'probe',('127.0.0.1',9999)); s.close()"
```
При необходимости замените `python` на имя Python 3 в своём окружении. Убедитесь, что `probe` появился в журналах всех трёх получателей. Отправитель также печатает каждую пересылку. Имена сервисов в журнале позволяют различить получателей.
Если с хоста сообщения не доходят (нет `forwarded`), отправляйте из контейнера: `docker compose exec sender python -c "..."`.
## Эксперимент: получатель пропустил сообщение
До запуска предположите, какие получатели увидят `m1` и `m2` и получит ли вернувшийся участник пропущенные данные.
1. Остановите третьего получателя:
```sh
docker compose stop receiver3
```
2. Отправьте `m1`:
```sh
python -c "import socket; s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.sendto(b'm1',('127.0.0.1',9999)); s.close()"
```
3. Верните третьего получателя:
```sh
docker compose start receiver3
```
4. Дождитесь **нового** сообщения `ready` от `receiver3` и снова отправьте `probe`. Убедитесь, что третий получатель его видит.
5. Отправьте `m2`, заменив в команде `b'm1'` на `b'm2'`.
При штатной работе стенда `m1` увидят первый и второй получатели, а `m2` — все три. Третий получатель не получит `m1` задним числом: программа не хранит историю и не запрашивает пропущенные сообщения. UDP допускает потери и без отключения получателя; успешная проба не является доказательством гарантированной доставки.
Обсудите:
- Какие действия выполняет `IP_ADD_MEMBERSHIP` и где задаётся адрес группы?
- Где в программе можно было бы добавить подтверждения или восстановление пропусков?
- Почему получение сетевого пакета и надёжная доставка сообщения приложению — разные события?
Пустая UDP-датаграмма тоже является сообщением: `b''` не означает закрытие соединения. Можно отправить её и затем обычное сообщение, чтобы проверить, что оба процесса продолжают работу.
Повторный запуск контейнера в этом эксперименте иллюстрирует пропуск данных. В домашнем задании используется модель crash-stop: отказавшие процессы не возвращаются.
## Завершение
Остановите просмотр журналов сочетанием Ctrl+C, затем удалите контейнеры стенда:
```sh
docker compose down
```