6

Bittorrent Peer Wire Protocol に関していくつか質問があります。この仕様を使用して Java で実装しようとしています。

Peer Wire Protocol セクションでは、すべての整数は 4 バイトのビッグ エンディアン値であると書かれています。私の知る限り、Javaはビッグエンディアンを使用しています。チョークメッセージを送信したい場合は、ということですか

チョーク:<len=0001><id=0>

sokcet 1 の後に 0 を書き込むだけですか?

私の2番目の質問について。作品をリクエストするとき、複数のファイルを 1 つの大きな連続したファイルと見なしますか? または個々のファイルで考えますか?ピースの長さがファイルと一致しないため、1 つのインデックスに 1 つのファイルの終わりと別のファイルの始まりの両方を含めることができますか?

ピアへの接続を開いてハンドシェイクを送信するときの最後の質問については、ピースをリクエストし続けるか、リクエストしてからしばらく待ってから、何かをリクエストするかどうかを確認しますか? 話はどのように行われますか?私は主にhttpタイプのネットワークプログラミングを行っており、何かを要求して応答を待ちます。しかし、作品をリクエストし続けたら、どのように作品を送るのですか?

4

1 に答える 1

7

質問1

シンプルなメソッドに固執し、ストリームベースの I/O を使用している場合は、プリミティブ型 (たとえば、byteintlongなど)を記述するときにDataInputStreamDataOutputStreamを使用します。

Socket s; // assume this is already connected
DataOutputStream out = new DataOutputStream( s.getOutputStream );
out.writeByte( 1 );
out.writeInt( 0 );
out.flush(); // optional

ノンブロッキング I/O (java.nio パッケージのクラスなど) を使用している場合は、ByteBufferを使用します。

Socket s; // assume this is already connected
SocketChannel = s.getChannel();
ByteBuffer buf = ByteBuffer.allocate(8); // two 4-byte integers
buf.put( 1 ).putInt( 0 );
buf.flip();
c.write( buf ); // assuming channel is writable :)

これらの各メソッドは、ユーザーに代わってバイト順の問題を処理します。

質問2

(通常、断片の断片であるブロックをワイヤ上で転送していることに注意してください。ここではそれについて詳しく説明します:))

あなたが言ったように、作品を送受信するときは、ファイル(またはファイル)が連続していると考えるのが最善です。.torrent ファイルには、info ディクショナリにファイル境界に関する情報が含まれています。複数ファイルの場合、各ファイルにはパスと長さがあります。単一ファイルのケースには、オプションの名前と長さがあります。ピースのサイズ、ピースの数、およびコンテンツの合計の長さ (すべて .torrent ファイルから) がわかっているため、受け取ったピースを「適切な場所に」配置することができます。

簡単なことは、トレントのサイズに等しい単一のファイルを作成することです。ピースを受け取ったら、この 1 つのファイル (「.downloading」ファイルと呼ばれることもあります) 内の正しいバイト オフセットに書き込みます。たとえば、次の 2 つのファイルで構成される torrent を考えてみましょう。

a/b/file1.txt [100 bytes]
a/b/file2.txt [200 bytes]

piece size (pz) = 50 bytes
total size (tz) = 100+200 = 300 bytes
number pieces (np) = 300/50 = 6
file = my_torrent.downloading

ピースとバイト オフセットにゼロから番号を付けるとします。ピース 1 のすべてを受け取ったとします。my_torrent.downloading の (開始) バイト オフセットは何ですか? (1*pz) = (1*50) = 50になります。ピース 0 はどこに行きますか? (0*pz) = (0*50) = 0で。等々...

これで、この .downloading ファイルを torrent 内の「実際の」コンテンツに変換する方法がわかると思います。

質問 3

BitTorrent swarm に参加すると、複数のピアとの間で同時にピースをアップロードおよびダウンロードすることになります。ちょっと考えてみてください。あるピアから作品をリクエストしているのと同時に、別のピアがあなたから同じことをしている可能性があります。あなたがすでに指摘したように、HTTPのセマンティクスとはかなり異なります。したがって、あなたの質問に直接答えるために、他のピアは関心のあるデータをあなたに尋ねます。:)

念のために、ピアからピースをリクエストする前に、ピアが必要なピースを持っていることを確認し(ビットフィールドをチェックしてメッセージを持っている)、適切なチョーキング/興味のある動作を尊重していることを確認してください。それを考えると、通常やりたいことは、既知のピアのリスト (トラッカーまたは DHT から通知されたもの) からデータをリクエストすることです。仕様はこれについて述べており、ここには多くの最適化と丁寧さに関する考慮事項があります。(たとえば、しっぺ返しの動作。)仕様では、これについて詳しく説明されていないことに気付くかもしれません。これは、BitTorrent クライアントの秘密のソースの多くが実装のこの部分にあるためです。:)

これがあなたの助けになることを願っています!

于 2009-06-22T21:51:26.920 に答える