LoginSignup
1
0

More than 3 years have passed since last update.

Dart で Torrentクライアントを作ろう(10+?) Dart で Mainline DHT を Codingしてみよう (5)  おわり

Last updated at Posted at 2015-08-14

GetPeersでInfoHashに対応するPeerを探す



* GetPeersでPeerを探す


* AnnouncePeerでP2Pネットワーク上に値を保存する



前章でP2Pネットワークを作成する事ができました。本章では、作成したP2Pネットワークにデータを記録する方法について解説していきます。

GetPeerでネットワークとFindNodeはほとんど同じ。

MainLine DHT ではGetPeersメッセージを利用して、データを所持しているPeerを探します。

GetPeerコマンドは「指定してKIDに対応するデータを所持しているPeerを知っていれば、そのPeerについて教えてもらう」、もしも知っていなければ、もっとも近いPeerを教えてもらう。といった事をします。

この操作を何度も繰り返す事で、KIDともっとも近くにあるNodeを発見する事ができます。

これは、ほとんど、FinddNodesと同じような動作ですね。
* KIDの近いPeerを紹介してもらうのが同じ
* なんども、送信と受信を繰り返すのが同じ

実装もほとんど同じになります。

AnnouncePeerでデータを記録する

GetPeerを繰り返して、上位K個のNodeが固定されたら、AnnounePeerメッセージを利用してデータを記録してもらいます。

K個のNodeへデータの記録を依頼します。複数のPeerへ依頼することによって、堅牢性が高まります。

  • 発見されやすくなる
  • 登録したPeerが離脱しても大丈夫
  • 登録したPeerの負荷を分散することができる。

メッセージの構成

arguments:  
{
  "t":"aa",
  "y":"q",
  "q":"get_peers", 
  "a": {
    "id" : "<querying nodes id>", 
    "info_hash" : "<20-byte infohash of target torrent>"
  }
}

response: have value
{
  "id" : "<queried nodes id>",
  "token" :"<opaque write token>",
  "values" : 
  ["<peer 1 info string>", "<peer 2 info string>"]
}

response: have node info
{
 "t":"aa",
 "y":"r",
 "r": {
  "id" : "<queried nodes id>",
  "token" :"<opaque write token>",
  "nodes" : "<compact node info>"
  }
}

FindNodeとほとんど同じですね。本書では"token"と"values"が初めて出てきました。

"token" は、レスポンスを返す側に自由に決めることができるバイトデータです。AnnouncePeerクエリを送信する時に使います。このバイトデータのサイズもレスポンスを返す側のクライアントによって、異なります。

"value" は、6バイトのデータ[ ,]をList形式で、複数個格納しています。

ref http://www.bittorrent.org/beps/bep_0005.html

実装について

findNodeで解説したとおりです。findNodeを実装したノウハウでそのままgetPeersも実装できると思います。
なので、特別、解説するページをさかないようにしました。

DHTを動作させてみよう


  • DHTを動作させてみよう!!*


DHTの解説は完了です。実際に動作させてみましょう。実際にTorrentのネットワークに繋がるアプりケーションを作ろうとすると、2〜3人日、またはそれ以上かかると思います。
作ってもらうのも良いのですが、
本章では hetimatorrentを利用したサンプルアプリを紹介します。

指定したKIDをネットワークから探すサンプル

main() {
  KNode node = new KNode(new HetiSocketBuilderChrome(), verbose: true);

  //
  node.start(ip: "0.0.0.0", port: 28080).then((_) {
    node.onGetPeerValue.listen((KGetPeerValue v) {
      print("---onGetPeerValue ${v.ipAsString} ${v.port} ${v.infoHashAsString} ");
    });
  });

  // initial node
  String initailNodeIp = "0.0.0.0";
  int initailNodePort = 38080;
  node.addBootNode(initailNodeIp, initailNodePort);

  // search target
  List<int> infoHash = new List.filled(20, 4);
  node.startSearchValue(new KId(infoHash), 18080, getPeerOnly: true);

  new Future.delayed(new Duration(minutes:30)).then((_){
    print(node.rootingtable.toInfo());
    return node.stop();
  });

}

UI付きのサンプルアプリは以下を参照してください。
https://github.com/kyorohiro/dart_hetimatorrent/tree/master/example/TorrentDHT

Ref

http://www.bittorrent.org/beps/bep_0005.html
http://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf

PS

Qiitaに投稿した、Torrentのチュートリアルと、この文章は、gitbookの方でメンテナンスしていきます。もう少し詳しく知りたい方はこちらを参照してください。
GitBook なぜなにTorrent hhttps://nazenani-torrent.firefirestyle.net
Dart用の作成したTorrent Libraryは以下で公開しています。
- https://github.com/kyorohiro/dart_hetimatorrent
- https://github.com/kyorohiro/dart_hetimatorrent/tree/master/example/TorrentDHT


Kyorohiro work

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0