Files
hse-2026/materials/07-naming-lookup/seminar/bittorrent/readme.md
T
2026-10-21 23:03:28 +03:00

71 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BitTorrent: участники, метаданные и проверка данных
В предыдущих опытах мы искали адрес сервиса. Теперь задача другая: найти участников, у которых есть нужный файл, и проверить полученные от них данные.
В BitTorrent участники раздачи называются **пирами**, а участник с полным файлом — **сидом**. **Трекер** сообщает клиенту контакты пиров. Сам файл передаётся между участниками.
Все команды выполняются из каталога `seminar`; [подготовка стенда](../readme.md#самостоятельный-запуск-опытов). Файлы и участники в опытах создаются локально.
## 1. Прочитать метаданные и проверить части
Файл `.torrent` описывает раздачу: содержит адрес трекера, сведения о содержимом и хеши частей. Рассматриваем формат BitTorrent v1 и раздачу одного файла.
**Перед запуском предскажите:**
1. Изменится ли infohash (идентификатор раздачи), если заменить только адрес трекера или комментарий в `.torrent`?
2. Что обнаружит проверка, если изменить один байт второй части полученного файла?
~~~powershell
docker compose run --rm -T tools python3 bittorrent/metadata.py demo --directory /work/metadata
~~~
Скрипт создаёт файл размером 256 KiB и метаданные с частями по 64 KiB, затем выполняет обе проверки. В выводе найдите:
| Поле | Смысл |
| --- | --- |
| `announce` | Адрес трекера |
| `name`, `length` | Имя файла и размер в байтах |
| `piece length` | Размер части |
| `pieces` | Хеши частей для проверки полученных данных |
Сведения о файле и частях находятся в словаре `info`. В v1 **infohash вычисляется как SHA-1 от исходных байтов этого словаря**, записанного в формате bencode — формате сериализации метаданных BitTorrent. Адрес трекера и комментарий находятся вне `info`, поэтому их замена сохраняет infohash, если байты `info` не менялись.
Для проверки файла каждая часть хешируется и сравнивается с соответствующим значением из `pieces`. В нашем учебном файле четыре одинаковые части, поэтому их хеши совпадают. После изменения байта проверка обнаруживает повреждение второй части — в выводе это индекс `1`.
Повторите проверку повреждённого файла отдельно:
~~~powershell
docker compose run --rm -T tools python3 bittorrent/metadata.py verify /work/metadata/lesson.torrent /work/metadata/damaged.bin
~~~
Ожидаем `FAILED bad pieces: [1]` и код завершения 1. Проверка подтверждает соответствие данных выбранным метаданным; доверие к самим метаданным остаётся отдельным вопросом.
## 2. Отключить трекер во время передачи
**Предскажите:** смогут ли продолжать загрузку клиент с уже найденным пиром и новый клиент, который ещё никого не знает?
В этом опыте другие способы поиска участников отключены: распределённый поиск (DHT), обмен контактами между пирами (PEX) и обнаружение в локальной сети. Новый клиент начинает без сохранённых контактов и может получить их только от трекера.
~~~powershell
docker compose run --rm -T tools python3 bittorrent/live.py
~~~
Скрипт запускает трекер и три клиента на основе библиотеки libtorrent. Они передают файл размером 4 MiB:
1. Сид регистрируется на трекере. Клиент `known` получает его контакт и начинает загрузку.
2. Трекер начинает отвечать HTTP 503 — «сервис недоступен». В этот момент запускается новый клиент `fresh`.
3. `known` продолжает получать данные и завершает загрузку. У `fresh` нет пиров и данных.
4. Трекер восстанавливается. После нового запроса `fresh` находит участников и тоже получает файл.
Сопоставьте строки `TRACKER`, `known`, `fresh` и `PASS` с этими этапами. Счётчик `bytes_done` показывает, сколько байтов содержимого уже есть у клиента; завершённые файлы дополнительно сверяются с исходным.
Трекер нужен для получения контактов. Продолжать обмен по уже установленному соединению можно и при его отказе. Результат для нового клиента зависит от условий: в обычной раздаче ему могут помочь другие способы обнаружения участников.
## Поиск без трекера
**Распределённая хеш-таблица (DHT)** позволяет искать контакты участников по infohash без обращения к трекеру. Для входа в DHT клиенту всё равно нужен контакт хотя бы одного её узла.
В BitTorrent Mainline DHT используется Kademlia. В [следующем разделе](../chord/readme.md) разберём Chord — другой алгоритм распределённого поиска из лекции.
Исходники: [чтение метаданных и проверка частей](metainfo.py), [опыты с метаданными](metadata.py), [локальная передача](live.py). Спецификации: [BEP 3](https://www.bittorrent.org/beps/bep_0003.html), [BEP 5](https://www.bittorrent.org/beps/bep_0005.html).