リクエストの中身
peer id を生成する
info 辞書 の Hashを生成する
portを用意する
アドレスを生成する
Get リクエストでデータ
実際に、Trackerサーバー とTrackerクライアント の間でやり取 りされるデータの形式について解析していきます。 Tracker はデータを配信している Peer の一覧を管理していま す。以前解説した通り、Torrentではデータをダウンロードする 側もデータの配信にまわるのでした。 Torrent ではこの仕組みを実現するために、Trackerへ自身を登 録する対価として、Peerの一覧を取得できるような仕組みにな っています。
データ配信に必要なものが入っている
データ配信に必要なものは、配信するデータ、配信するサーバ ーのIPアドレス、配信するサーバーのポート番号、配信する端 末のID、どのデータを配信かるかの情報です。 まず一つ目、配信するデータは、Trackerに初めてアクセスす る時には持っていないものなので、ここでは除外しましょう。
次に必要と思われるのが、IPアドレスです。このアドレスも用 意する必要ありません。TrackerがあなたのIPアドレスを知って いるからです。具体的には、Trackerにアクセスする際に、自身 のIPアドレスをTrackerは知る事ができます。 例えば、Httpサーバーで通信相手のIPアドレスを返すようなプ ログラムは以下のような感じで書けます。
このように、Httpサーバーは、相手のIPアドレスを知っていま す。なので、リクエストに含める必要はなさそうです。 その次に必要と思われるのはポート番号です。他のPeerからの 接続を待ち受けるには、IPアドレスとPort番号が必要です。 Tracker は待ち受けしている Port 番号を IPアドレス のように 知るすべはありません。リクエストとして通知してあげる必要 がありそうです。
最後に、IDが必要です。Peerを識別する情報としてIPアドレス を利用する方法が考えられます。しかし、IPアドレスは複数の 端末で共有している場合や、通信環境によっては同一のIPアド レスを長時間維持するができなかったりします。 そこで、Peerごとに識別子を自身で生成して、それを利用しま す。
もう一つ、必要なものがありました。どのデータをダウンロー ドしたいかといった情報です。Trackerは同一のアドレスで多数 のデータを配信するPeerを管理することがあります。どのデー タを配信してほしいのかを Tracker に通知する必要がありま す。
だいたい、リクエストら必要な情報が見えてきました。具体的 にGetリクエストで使用する値について見ていきましょう。
Info辞書からIDを生成
まずは、どのデータをダウンロードしたいかを指定するための IDを用意しましょう。 Torrent が扱う全てのデータは衝突しな い固有の識別子を持っています。これは、ひとつの配信データ を複数の Tracker で管理したい場合に有効な方法です。唯一の IDで有るならば、このTrackerで管理しても、関係のないデー タが混ざる事がないからです。このような方法を用いる事で、 Tracker への負荷を分散する事が可能になります。 では、どのように唯一IDを生成するのでしょうか。特定の管理 団体などにIDをもらう必要があるのでしょうか?Torrentでは SHA1 が用いられています。 SHA1 は、全てのデシタルデータに 160bit(20byte) の ID をふ るアルゴリズムです。2の160乗のIDの振る事ができますから、 異なるデータなのに、同じIDを振られる事はありません。
Torrentでは、Info辞書のSHA1をとりIDとして利用します。 Dartでは以下のように書けます。
class PeerIdCreator { static math.Random _random = new math.Random(new DateTime.now().millisecond); static List createPeerid(String id) { List output = new List(20); for (int i = 0; i < 20; i++) { output[i] = _random.nextInt(0xFF); } List idAsCode = id.codeUnits; for(int i=0;i<5&&i<idAsCode.length;i++) { output[i+1] = idAsCode[i]; } return output; }
{ HttpServer.bind(address, port).then((io.HttpServer server) { server.listen((HttpRequest request) { request.response.write(request.connectionInfo.remoteAddress.toString();); request.response.close(); }); }); }
String toString() { return scheme + "://" + trackerHost + ":"
trackerPort.toString() + ""
path + toHeader();
}
String toHeader() { return "?" + KEY_INFO_HASH + "=" + infoHashValue
"&" + KEY_PORT + "=" + port.toString()
"&" + KEY_PEER_ID + "=" + peerID
"&" + KEY_EVENT + "=" + event
"&" + KEY_UPLOADED + "=" + uploaded.toString()
"&" + KEY_DOWNLOADED + "=" + downloaded.toString()
"&" + KEY_LEFT + "=" + left.toString();
}
```
といった感じで書けます。無事URLを生成する事ができましたね。
Kyorohiro work
Last updated