FindNodeを実装
MainLine DHT は、UDPで通信
通信ライブラリとして、hetimanetを使用しています。APIのインターフェイスは他の通信ライブラリと大きな違いはありません。なので、お使いのものと読み替えて読み進めてください。
RootingTableに、FindeNodeの機能を追加する
所持しているPeerInfoを指定されたKIDでソートして探す。
class KRootingTable {
...
...
...
List<KPeerInfo> findNode(KId id) {
List<KPeerInfo> ids = [];
for (KBucket b in _kBuckets) {
for (KPeerInfo i in b.iterable) {
ids.add(i);
}
}
ids.sort((KPeerInfo a, KPeerInfo b) {
return a.id.xor(id).compareTo(b.id.xor(id));
});
List<KPeerInfo> ret = [];
for (KPeerInfo p in ids) {
ret.add(p);
if (ret.length >= _kBucketSize) {
return ret;
}
}
return ret;
}
...
...
}(1) KNodeはUDPサーバー機能を持つ。
まずは、UDPを用いて、通信部分を書いてみましょう。Torrentの仕様では、DHTとして動作するPeerをNodeと読んでいます。 DHTの通信を行う主体として、KNode class を定義することにします。
UDP serverは、メッセージを受け取るメッセージはbencodeなのでした。パースしてそのMessageを使うclassに渡します。
(2) Krpc Messageをパースする機能を持つ
MainLine DHT では、PeerとPeerの通信には、Bencodeが利用されます。 すでにBencodeのパーサーは作成ずみなので、難しいことはないはずです。
こんな感じです。あとは、必要に応じて、パースした結果を読み取るだけです。
こんな感じです。BEP5のスペックをみると結構ありますがも気長にコーディングしていけば、半日くらいで終わると思います。
(3) メッセージを送信する機能を持つ
メッセージの送信は、受信用に作成したUDPSocketを利用します。こうすることで、受信相手に、ポート番号を伝えることができます。
(4) ネットワークへの参加用のコードを書く
RootingTableに所持しているデータの中から、自分自信ともっとも近いKIDをもつPeerへFindNodeクエリを送信する
レスポンスを受けとったら、もう一度繰り返す
一定時間だったら、もう一度アクセスする
(5) FindeNodeクエリに対応したレスポンスを返せるようにしよう
Last updated