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 !