Протокол Bittorrent Peer Wire, реализованный на Java

У меня есть пара вопросов относительно протокола Bittorrent Peer Wire. Я пытаюсь реализовать его на Java, используя эту спецификацию.

В разделе Peer Wire Protocol говорится, что все целые числа представляют собой четырехбайтовые значения с прямым порядком байтов. AFAIK java использует обратный порядок байтов. Означает ли это, сказать, если я хочу отправить задушенное сообщение

дроссель:‹len=0001›‹id=0›

Мне просто написать в сокет 1, а затем 0?

Что касается моего второго вопроса. при запросе части я думаю, что несколько файлов как один большой непрерывный файл? или думаете отдельными файлами? потому что длина фрагмента не будет соответствовать файлам, поэтому один индекс может содержать как конец одного файла, так и начало другого?

Что касается моего последнего вопроса, когда я открываю соединение с одноранговым узлом и отправляю свое рукопожатие, я просто продолжаю запрашивать части или запрашивать, а затем ждать некоторое время, чтобы увидеть, запросит ли он что-то от нас? как происходит разговор? В основном я занимался сетевым программированием типа http, где я что-то прошу и жду ответа. но если я буду продолжать запрашивать части, как я буду отправлять части?


person Hamza Yerlikaya    schedule 21.06.2009    source источник


Ответы (1)


Вопрос 1

Придерживаясь простых методов, если вы используете поточный ввод-вывод, используйте DataInputStream и DataOutputStream при записи примитивных типов (например, byte, int, long и т. д.):

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

Если вы используете неблокирующий ввод-вывод (например, классы из пакета 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 содержит информацию о границах файла в информационном словаре. В многофайловом случае каждый файл имеет путь и длину; однофайловый случай имеет необязательное имя и длину. Поскольку вы знаете размер фрагмента, количество фрагментов и общую длину контента (все из файла .torrent), вы можете размещать фрагменты «в нужном месте» по мере их получения.

Простая вещь — создать один файл, равный размеру торрента. Когда вы получите фрагмент, запишите его с правильным смещением в байтах в этом единственном файле (иногда называемом файлом «.downloading»). Например, рассмотрим торрент, состоящий из двух файлов:

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 в «настоящий» контент внутри вашего торрента.

Вопрос 3

Участвуя в рое BitTorrent, вы одновременно загружаете и скачиваете фрагменты на несколько пиров и с них. Подумайте об этом на секунду. В то же время, когда вы запрашиваете кусок у какого-то пира, другой пир может делать то же самое у вас. Как вы уже указали, это сильно отличается от семантики HTTP. Итак, если говорить непосредственно о вашем вопросе, другие сверстники будут запрашивать у вас интересующие их данные. :)

Просто чтобы удостовериться, прежде чем запрашивать фрагмент a у пира, убедитесь, что у пира есть нужный вам фрагмент (ознакомьтесь с битовое поле и иметь сообщения), и вы соблюдали надлежащее удушье/заинтересованность поведение. Учитывая это, то, что вы обычно хотите сделать, это запросить данные из вашего списка известных пиров (о которых вам сообщил трекер или DHT) в наиболее редком порядке. Спецификация говорит об этом, и здесь есть МНОГО оптимизаций и соображений вежливости. (Например, поведение «око за око».) Вы могли заметить, что spec не означает многое из этого. Это потому, что в этой части реализации кроется большая часть секретного соуса клиентов BitTorrent. :)

Я надеюсь, что это поможет вам немного!

person JLR    schedule 22.06.2009
comment
обратите внимание, что согласно спецификации поле id представляет собой один байт, а не целое число. - person Michael Borgwardt; 23.06.2009