Проектная лаборатория
Собственный BitTorrent
Этап 14 · Magnet-ссылки
Отправка рукопожатия расширений
Русский перевод заданий CodeCrafters. Примеры подготовлены для Go. Выбор языка меняет команды и результаты, но не текст задания.
На этом этапе вы отправите список расширений, поддерживаемых вашим клиентом.
Идентификаторы расширений и рукопожатие
Каждый пир хранит соответствие между именами расширений и идентификаторами. Одному имени расширения у разных пиров могут соответствовать разные идентификаторы, но для конкретного пира идентификатор остаётся постоянным.
Для общения с другими пирами через расширение метаданных ваш пир должен знать идентификатор, используемый удалённым пиром для этого расширения. Имя расширения метаданных — ut_metadata. Чтобы узнать идентификатор, нужно отправить сообщение рукопожатия расширений и дождаться соответствующего ответного сообщения пира.
Сообщение рукопожатия расширений содержит такой словарь:
{
"m": {
"ut_metadata": 16,
... (other extension names and IDs)
}
}В этом примере 16 — идентификатор расширения метаданных, используемый пиром. Это лишь пример: можно выбрать любое значение идентификатора.
Программа должна отправить сообщение рукопожатия расширений вскоре после получения сообщения битового поля. Общая последовательность:
- Установить TCP-соединение с пиром.
- Отправить сообщение базового рукопожатия.
- Получить сообщение базового рукопожатия.
- Отправить сообщение битового поля (в этом задании можно пропустить).
- Получить сообщение битового поля.
- Если пир поддерживает расширения (судя по зарезервированному биту базового рукопожатия):
- Отправить сообщение рукопожатия расширений.
- Получить сообщение рукопожатия расширений.
Обратите внимание: сообщение рукопожатия расширений отправляется только тогда, когда удалённый пир поддерживает расширения, о чём сообщает зарезервированный бит базового рукопожатия. Так сохраняется обратная совместимость с пирами без поддержки расширений.
На этом этапе мы реализуем отправку сообщения рукопожатия расширений. Получение реализуем на следующем этапе.
Формат рукопожатия расширений
Сообщения расширений следуют стандартному формату сообщений BitTorrent:
- Префикс длины сообщения (4 байта).
- Идентификатор сообщения (1 байт).
- Для всех сообщений, реализованных расширениями, равен 20.
- Полезная нагрузка (переменный размер).
Структура полезной нагрузки:
- Идентификатор сообщения расширения (1 байт).
- Для рукопожатия расширений равен 0.
- Словарь bencode (переменный размер).
- Содержит ключ "m", значением которого является другой словарь.
- Внутренний словарь сопоставляет имена поддерживаемых расширений соответствующим идентификаторам сообщений.
- Например,
{"ut_metadata": 1, "ut_pex": 2}означает, что пир поддерживает расширения "ut_metadata" и "ut_pex" с идентификаторами 1 и 2 соответственно.
Нас интересует имя "ut_metadata", соответствующее расширению метаданных.
Тесты
Тестирующая система запустит вашу программу следующим образом:
$ ./your_program.sh magnet_handshake <magnet-link>Ожидаемый вывод:
Peer ID: 0102030405060708090a0b0c0d0e0f1011121314Вывод совпадает с предыдущим этапом. Дополнительно тестирующая система проверит, что:
- Получено сообщение рукопожатия расширений.
- Оно содержит словарь вида
{"m": {"ut_metadata": <PICK YOUR ID>}}. - Идентификатор для
ut_metadataнаходится в диапазоне от 1 до 255: он должен представляться 8-битным беззнаковым целым числом, отличным от 0.
Примечания
- Программа должна отправлять рукопожатие расширений только если пир поддерживает расширения.
- Чтобы это определить, проверьте зарезервированные байты сообщения базового рукопожатия.
- Сообщение рукопожатия расширений описано в разделе о рукопожатии документации протокола расширений.
Проверка в вашей IDE
Нужны Node.js, Git, Go 1.24+ для тестеров и инструменты выбранного языка. Тестеры загружаются и запускаются локально; отдельным проектам нужны дополнительные системные зависимости.
Настройка проекта и IDE
1. Создайте проект один раз
node '/opt/graphlms/tools/project-lab/cli.mjs' init bittorrent ./my-bittorrent --language go2. Откройте папку в IDE
cd ./my-bittorrentРеализуйте требования этапа в созданном проекте.
Запустите из папки проекта
node '/opt/graphlms/tools/project-lab/cli.mjs' submit --stage xi4Запускайте submit из папки проекта. Это локальные проверки, а не сертификаты или результаты аккаунта CodeCrafters.
Результат проверки
go / ЛОКАЛЬНОПодключение к локальной проверке…
Здесь появится результат
Запустите submit в терминале. Страница обновляет результаты каждые 8 секунд.