スクラッチから直接実装したBitTorrentクライアント
(github.com/piyushgupta53)- このオープンソースプロジェクトは、Go言語で実装されたBitTorrentクライアントであり、ファイルダウンロードの基本ロジックを独自実装している
- Bencodeのエンコード/デコードを直接処理し、強力なエラー検証機能を備えている
.torrentファイルの解析、Infoハッシュの計算、ピア間通信などの中核機能を包括的にサポートしている- 同時ダウンロード、ファイルの組み立て、ブロック単位の保存管理など、実運用性を高める機能を含んでいる
- 既存のBitTorrentオープンソースと比較して、Go言語のシンプルさ、コード構造の明確さ、モジュール化に強みがある
概要
このプロジェクトは、Go言語でBitTorrentクライアントを直接実装したもの
BitTorrentプロトコルを使ったファイルダウンロード機能を独自開発の形で提供する
主に、torrentファイルの解析、ピア探索、ファイルダウンロード機能を扱っている
主な機能
-
Bencodeのエンコード/デコード
- 文字列、整数、リスト、辞書など、すべてのBencode型をサポート
- 強力なエラー処理とデータ検証を適用
-
torrentファイル処理
- 単一ファイルおよびマルチファイルtorrentの両方を解析可能
- Infoハッシュおよび各ピースのハッシュを抽出し、すべての標準フィールドをサポート
-
ピア探索と通信
- HTTPトラッカーをサポート
- ピア間ハンドシェイクプロトコルを実装
- BitTorrentメッセージプロトコルとピア接続管理を実行
-
ダウンロード機能
- ピースおよびブロック単位の管理
- 同時ダウンロード処理
- ダウンロード進捗の追跡とファイルの組み立て
- ブロック単位のストレージ管理による効率性を提供
プロジェクト構成
- cmd/ : コマンドラインインターフェースおよび実行ファイル
- internal/
- bencode/ : Bencodeのエンコードおよびデコード機能
- torrent/ : torrentファイルの解析および処理
- tracker/ : トラッカープロトコルの実装
- peer/ : ピア間通信機能
- download/ : ダウンロード管理機能
- pkg/ : 外部公開可能なパッケージ群
要件
- Go 1.21以上が必要
使い方
- 現在はプロジェクト初期開発段階のため、使い方の案内は今後追加予定
開発状況と計画
- 現在活発に開発進行中
- 詳細な開発段階はcheckpoint.mdファイルに記録
- 今後の計画:
- Magnetリンクのサポート
- メタデータ交換プロトコル
- DHT(分散ハッシュテーブル)のサポート予定
参考資料
- BitTorrentプロトコル仕様
- Bencode仕様
プロジェクトの重要性と強み
- このプロジェクトは、Go言語特有のシンプルな文法と並行性を活かし、BitTorrentクライアントの複雑な要素を明確にモジュール化して実装している
- 構造が明確で、拡張性・保守性の面から学習用途と実運用の両方に利点がある
- 比較的初期段階でありながら、BitTorrentプロトコルの中核機能を迅速に実現している
1件のコメント
Hacker News のコメント
bencode デコーダーでは動的メモリ割り当てのサイズに上限を設けたほうがよい、という提案。torrent ファイルや announce から入ってくる入力値は信頼できないため、悪意ある入力によって非常に大きな割り当て要求が発生し、サービス拒否(DoS)を引き起こす可能性がある。文字列パースでは、適切な上限を残りの入力長に設定でき、正しい torrent であればファイルの残り長より長い文字列を持つことはない
プロジェクトがきれいでシンプルに見えて良い。Readme にワンライナーの使用例を追加するとさらによさそう。たとえば
./go-torrent My-Linux-Distro-Wink-ISO.torrentのような使い方を示す一文を追加するのがおすすめ。もしtorrent.ParseFromUrl機能も加わればさらに高評価。こういう体験は、誰にとっても自分なりの「精神的な旅」としてやってみる価値があるcodecrafters が提供している似たチャレンジの紹介。この過程では進行やテストなども支援してくれて、無料の1か月で試してみたがかなり面白かった
https://app.codecrafters.io/courses/bittorrent/overview
Go 開発者ではない立場から、なぜ古い Go 1.21 を使っているのか気になる。特に旧バージョンにこだわる理由があるのかという質問。調べると10か月前にすでにサポート終了していた
Windows 7 のサポートのため。Go 1.21.4 以下で書かれたプロジェクトは、2009年以降のほぼすべての Windows とあらゆるコンピュータで動作するが、1.21.5 以上を使うと最新のコンピュータと Windows 10、11 でしか動かず、特別な利点もない
https://github.com/golang/go/issues/64622
README は AI が書いた可能性が高い。実際の
go.modファイルでは Go バージョンが 1.23.1 に指定されているので、結果的に 1.23.1 以上が必要https://github.com/piyushgupta53/go-torrent-client/blob/6130f4e/go.mod#L3 https://go.dev/doc/modules/gomod-ref#go-notes
本当に素晴らしいプロジェクト。大学時代にジョージア工科大学のネットワーキングの授業でこれを最終課題としてやったことがあり、コードは失われたが学んだ教訓は一生残っている。こういうプロジェクトは新しい言語を身につけるのにとても良い方法
マグネットリンクをサポートしているかという質問。
Edit: 今後追加される機能だとわかった
どうやってこれを作ったのか気になる。プロトコル仕様を直接見たのか、それとも他の実装を参考にしたのかという質問。こういうものをゼロからどう実装するのか、いつも気になっていた
https://www.bittorrent.org/beps/bep_0003.html
追加の拡張については
https://www.bittorrent.org/beps/bep_0000.html
作業を非常に小さな単位に分割して、自分で結果を確認しながら進めるのが重要。たとえば
.torrentファイルのパースから始めたが、bencoding を自分で実装する必要があった。Arch Linux 用の.torrentをダウンロードしてみるとフォーマットが不正で、url-listのような予想外のキーが出てきた。調べてみると bep_0019 に関連していた。最終的には Debian Linux の.torrentファイルを正しくパースできたその後、トラッカーへの announce HTTP リクエストとピアプロトコルも実装した。ピアプロトコルはかなり難しく、実験的な姿勢が大いに役立った。Debian の torrent から announce URL を削除してピアがまったくいない状態にしたうえで、KTorrent に自分のクライアントを手動で追加し、やり取りされるメッセージを観察して、その結果をもとにコードを修正した。非常に多くの試行錯誤とデバッグの過程があった
細かいプロトコル仕様の中には、どうしても公式文書で見つからず、ちょっとしたことを ChatGPT に尋ねたこともあるし、クライアントごとに実装が少しずつ違うため、詳細なアルゴリズムは明確ではない。どのブロックを受け取るか、どのピアに接続するか、choke/unchoke をどう動かすかなどはきちんと整理されていない。Web 検索が大いに役立つ
さらに https://wiki.theory.org/Main_Page にも役立つ情報がある
現在は KTorrent と完全なダウンロード/アップロードが可能な段階。今後はトラッカーからピアを取得し、ダウンロードするブロックを選定してファイルに保存するアルゴリズムの開発が残っている
もっと詳しい過程が気になれば、いつでも質問してほしい
GUI の追加はどれくらい難しいかという質問。Go で GUI を実装した例をあまり見たことがない
個人的には ImGui ラッパーの https://github.com/AllenDang/giu が好み
もっとも高機能なのは unison だが、実際に広く使われているかはよくわからず、ドキュメントもかなり不足していそう https://github.com/richardwilkes/unison
Gio は新しいスタイルの GUI フレームワークで、Tailscale や gotraceui で使われている https://gioui.org
Wails は Web 開発経験があれば習得しやすい https://wails.io
GTK4 バインディングもよさそう https://github.com/diamondburned/gotk4
Cogent Core も面白そうだが、自分は Go の代わりに Odin 言語へ移る前に少し触っただけ https://www.cogentcore.org/core
Fyne は個人的には複数のコンピュータや OS でパフォーマンス面の問題が多かったが、とにかくもっとも有名な GUI フレームワークではある https://fyne.io
こういうプロジェクトに興味があって、一度やってみようかと思っていた。どれくらい難しいのか、完成度はどの程度だと思うのか、DHT、Magnet、NAT traversal のような複雑な機能まで実装したのかが気になる。実際、市場にあるほぼすべての torrent をカバーするには何が必須なのか、その機能一覧すらよくわからない。torrent 関連のプロトコルがあまりに多く、全体像も各プロトコルの役割も把握できていない
難しさは経験、言語習熟度、実験的な姿勢によって大きく変わる。たとえば自分も先週 Go で BitTorrent クライアントを作り始めたが、1週間でここに出ているプロジェクトの 80% 程度まで到達した。Go とプロトコル、ネットワーキングの知識があり、試行錯誤に慣れているので進みが速かった
BitTorrent の公式仕様自体は本当に短く、1時間ほどで読んで理解できる https://www.bittorrent.org/beps/bep_0003.html
ただし周辺の拡張プロトコルは非常に多く、各クライアントで対応状況も異なる。たとえばプロトコル暗号化(実際には難読化)をまず試し、だめなら通常のプロトコルに切り替えることが多い
もし Linux ディストリビューションのように公式の
.torrentファイルでダウンロードするだけなら、難易度は確かに低い。たいていは単一ファイルで、トラッカーもあり、標準プロトコルを話すピアがほとんどなので、NAT 環境でも内部ポートを開けずに十分動作するもちろん一般的な torrent(とくにグレーゾーンのもの)を扱いたいなら、magnet リンクのパース、ピア探索のための DHT、自動ポートマッピングのための UPnP などを順次追加していく必要がある。ただ、それでも機能ごとに段階を分けて実装していくことは可能。機能が増えるほど、見つけられるピアも増え、やり取りの成功率も上がる
かなり挑戦的で、プロトコルや bencoding の仕組みを学び、全体構造を頭の中で描いてからコードを書くまでにほぼ1か月かかった。Magnet と DHT はまだ未対応
v2 と mutable torrents が実装されているかという質問。ぜひ mutable torrents は実装してほしいという希望も伝えている