6 Stimmen

Implementierung des Bittorrent Peer Wire Protokolls in Java

Ich habe ein paar Fragen zum Bittorrent Peer Wire Protocol. Ich versuche, es in Java zu implementieren, indem ich diese Spezifikation .

Im Abschnitt "Peer Wire Protocol" heißt es, dass alle Ganzzahlen Vier-Byte-Big-Endian-Werte sind. AFAIK verwendet Java big endian. Bedeutet das, dass ich, wenn ich eine Choke-Nachricht senden möchte

choke:<len=0001><id=0>

Schreibe ich einfach eine 1 gefolgt von einer 0 in das Sokcet?

Was meine zweite Frage betrifft: Wenn ich ein Stück anfordere, denke ich dann an mehrere Dateien als eine große, zusammenhängende Datei? oder denke ich in einzelnen Dateien? weil die Stücklänge nicht mit den Dateien übereinstimmt, so dass ein Index sowohl das Ende einer Datei als auch den Anfang einer anderen enthalten kann?

Was meine letzte Frage betrifft, wenn ich eine Verbindung zum Peer öffne und meinen Handshake sende, fordere ich dann einfach weiter Stücke an oder warte eine Weile, um zu sehen, ob er etwas von uns anfordert? wie findet das Gespräch statt? Ich habe meistens Netzwerkprogrammierung vom Typ http gemacht, wo ich um etwas bitte und auf eine Antwort warte. aber wenn ich immer wieder Stücke anfordere, wie soll ich dann Stücke senden?

7voto

JLR Punkte 1078

Frage 1

Um bei einfachen Methoden zu bleiben, verwenden Sie bei der Verwendung von Stream-based I/O DataInputStream y DataOutputStream beim Schreiben primitiver Typen (z. B., Byte , int , lang , usw.):

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

Wenn Sie nicht-blockierende E/A verwenden (z. B. Klassen aus dem java.nio-Paket), verwenden Sie ByteBuffer s:

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 :)

Jede dieser Methoden wird sich in Ihrem Namen um die Bestellung von Byte kümmern.

Frage 2

(Beachten Sie, dass Sie normalerweise die Blöcke die Fragmente von Stücken sind, auf dem Draht. Ich werde das hier übergehen :) )

Beim Senden/Empfangen von Teilen ist es am besten, die Dateien (oder die Datei) als fortlaufend zu betrachten, wie Sie sagten. Die .torrent-Datei enthält Informationen über Dateigrenzen im Info-Wörterbuch. In der Mehraktenverfahren hat jede Datei einen Pfad und eine Länge; die Einzelaktenordner hat einen optionalen Namen und eine optionale Länge. Da Sie die Stückgröße, die Anzahl der Stücke und die Gesamtlänge des Inhalts kennen (alles aus der .torrent-Datei), können Sie die Stücke an der richtigen Stelle platzieren, wenn Sie sie erhalten.

Es ist einfach, eine einzelne Datei zu erstellen, die der Größe des Torrents entspricht. Wenn Sie ein Stück erhalten, schreiben Sie es an den richtigen Byte-Offset innerhalb dieser einzelnen Datei (manchmal auch ".downloading" genannt). Nehmen wir zum Beispiel einen Torrent, der aus zwei Dateien besteht:

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

Angenommen, wir nummerieren Stücke und Byte-Offsets beginnend mit Null. Angenommen, Sie erhalten das gesamte Stück 1. An welchem (Start-)Byte-Offset wird es in my_torrent.downloading abgelegt? Es beginnt bei (1*pz) = (1*50) = 50 . Wohin gehört das Stück 0? Bei (0*pz) = (0*50) = 0 . Und so weiter...

Ich wette, dass du jetzt herausfinden kannst, wie du diese .downloading-Datei in den "echten" Inhalt deines Torrents verwandelst.

Frage 3

Wenn Sie an einem BitTorrent-Schwarm teilnehmen, laden Sie Teile zu und von mehreren Peers hoch und runter gleichzeitig . Denken Sie eine Sekunde darüber nach. Zur gleichen Zeit, in der Sie einen Beitrag von einem anderen Teilnehmer anfordern, könnte ein anderer Teilnehmer das Gleiche von Ihnen verlangen. Das ist etwas ganz anderes als die Semantik von HTTP, wie Sie schon sagten. Um also direkt auf Ihre Frage einzugehen, werden andere Peers Sie nach Daten fragen, die sie interessieren :)

Bevor Sie ein Stück von einem Peer anfordern, sollten Sie sich vergewissern, dass dieser Peer das gewünschte Stück hat (sehen Sie sich die Bitfeld und haben Nachrichten ) und Sie haben die richtige würgend/interessiert Verhalten. In Anbetracht dessen sollten Sie normalerweise Daten von Ihrer Liste bekannter Peers (die Ihnen vom Tracker oder DHT mitgeteilt wurden) in Seltenste zuerst bestellen. In der Spezifikation ist davon die Rede, und es gibt hier eine Menge Optimierungen und Höflichkeitsüberlegungen. (Tit-for-tat-Verhalten, zum Beispiel.) Sie werden feststellen, dass die spec Vieles davon ist nicht klar formuliert. Das liegt daran, dass ein großer Teil der geheimen Sauce von BitTorrent-Clients in diesem Teil der Implementierung liegt :)

Ich hoffe, das hilft Ihnen ein wenig!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X