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

  • 0
    いいね
  • 0
    コメント
    この記事は最終更新日から1年以上が経過しています。

    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 https://www.gitbook.com/book/kyorohiro/doc_hetimatorrent/details
    Dart用の作成したTorrent Libraryは以下で公開しています。
    - https://github.com/kyorohiro/dart_hetimatorrent
    - https://github.com/kyorohiro/dart_hetimatorrent/tree/master/example/TorrentDHT


    Kyorohiro work

    http://kyorohiro.strikingly.com