6 votes

Mise en œuvre du protocole Bittorrent Peer Wire en Java

J'ai quelques questions concernant le protocole Bittorrent Peer Wire. J'essaie de le mettre en œuvre en Java en utilisant cette spécification .

Dans la section relative au protocole Peer Wire, il est indiqué que tous les nombres entiers sont des valeurs big endian de quatre octets. AFAIK java utilise big endian. Cela signifie-t-il que si je veux envoyer un message choke

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

Dois-je simplement écrire dans le sokcet 1 suivi de 0 ?

Pour ce qui est de ma deuxième question, lorsque je demande une pièce, dois-je considérer plusieurs fichiers comme un seul grand fichier continu ou penser en fichiers individuels ? parce que la longueur de la pièce ne s'aligne pas sur celle des fichiers, de sorte qu'un index peut contenir à la fois la fin d'un fichier et le début d'un autre ?

Pour ce qui est de ma dernière question, lorsque j'ouvre une connexion avec le pair et que j'envoie ma poignée de main, est-ce que je continue à demander des pièces ou est-ce que je demande puis attends un moment pour voir s'il va nous demander quelque chose ? J'ai surtout fait de la programmation réseau de type http où je demande quelque chose et j'attends une réponse. mais si je continue à demander des pièces, comment vais-je les envoyer ?

8voto

JLR Points 800

Question 1

Si l'on s'en tient à des méthodes simples, si l'on utilise des E/S basées sur des flux, il faut utiliser Flux de données y Flux de données lors de l'écriture de types primitifs (par ex, octet , int , long etc :)

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

Si vous utilisez des E/S non bloquantes (par exemple les classes du paquetage java.nio), utilisez alors 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 :)

Chacune de ces méthodes s'occupera des questions de commande d'octets en votre nom.

Question 2

(Notez qu'en général, vous transférez blocs qui sont des fragments de pièces, sur le fil. Je n'y reviendrai pas ici :) )

Lors de l'envoi et de la réception de morceaux, il est préférable de considérer les fichiers (ou le fichier) comme continus, comme vous l'avez dit. Le fichier .torrent contient des informations sur les limites des fichiers, dans le dictionnaire d'informations. Dans le dictionnaire dossier multiple chaque fichier a un chemin d'accès et une longueur ; la fonction dossier unique a un nom et une longueur optionnels. Comme vous connaissez la taille des morceaux, leur nombre et la longueur totale du contenu (tout cela à partir du fichier .torrent), vous pouvez placer les morceaux "au bon endroit" au fur et à mesure que vous les recevez.

Il suffit de créer un fichier unique de la taille du torrent. Lorsque vous recevez un morceau, écrivez-le à l'emplacement de l'octet correct dans ce fichier unique (parfois appelé fichier ".downloading"). Prenons l'exemple d'un torrent composé de deux fichiers :

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

Supposons que nous numérotons les pièces et les décalages d'octets en commençant par zéro. Supposons que vous receviez la totalité du morceau 1. À quel décalage d'octet (de départ) correspond-il dans le fichier my_torrent.downloading ? Il va à (1*pz) = (1*50) = 50 . Où va la pièce 0 ? A (0*pz) = (0*50) = 0 . Et ainsi de suite...

Je parie que vous savez maintenant comment transformer ce fichier .downloading en "vrai" contenu de votre torrent.

Question 3

Lorsque vous participez à un essaim BitTorrent, vous chargez et téléchargez des éléments vers et depuis plusieurs pairs. simultanément . Réfléchissez-y un instant. Au moment où vous demandez une pièce à un pair, un autre pair peut faire de même avec vous. C'est tout à fait différent de la sémantique du HTTP, comme vous l'avez déjà souligné. Donc, pour répondre directement à votre question, d'autres pairs vous demanderont des données qui les intéressent :)

Avant de demander un morceau à un pair, assurez-vous que ce dernier possède le morceau que vous souhaitez (consultez la rubrique et ont des messages ) et que vous avez respecté les étouffé/intéressé comportement. Dans ces conditions, ce que vous voulez normalement faire, c'est demander des données à votre liste de pairs connus (que le tracker ou le DHT vous a indiqué) dans la rubrique le plus rare des premiers ordre. La spécification en parle et il y a BEAUCOUP d'optimisations et de considérations de politesse à ce sujet. (Vous pouvez remarquer que l'option spécimen ne précise pas grand-chose. C'est parce qu'une grande partie de la sauce secrète des clients BitTorrent réside dans cette partie de l'implémentation :)

J'espère que cela vous aidera un peu !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X