Add week 7 materials
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user