Вопрос

Я реализую протокол BitTorent с использованием Java с помощью этой спецификации . В разделе сообщений все сообщения имеют фиксированную длину, кроме 2 из них; для одного из них это единственное переменное сообщение после рукопожатия, поэтому я могу проверить другие и предположить, что это частичное сообщение, когда другие сообщения не встречались. Но для следующего сообщения

bitfield: <len=0001+X><id=5><bitfield>
     

Сообщение битового поля может быть отправлено только сразу после завершения последовательности квитирования и до отправки любых других сообщений. Это необязательно, и его не нужно отправлять, если у клиента нет частей.

     

Сообщение битового поля имеет переменную длину, где X - длина битового поля. Полезная нагрузка - это битовое поле, представляющее фрагменты, которые были успешно загружены. Старший бит в первом байте соответствует индексу 0 фрагмента. Биты, которые очищены, указывают на отсутствующий фрагмент, а установленные биты указывают действительный и доступный фрагмент. Запасные биты в конце установлены на ноль.

     

Битовое поле неправильной длины считается ошибкой. Клиенты должны разорвать соединение, если они получают битовые поля, которые имеют неправильный размер, или если битовое поле имеет какой-либо из установленных резервных битов.

Я не могу придумать способ разобрать его, если не знаю длины; Как я должен найти идентификатор в потоке байтов?

Редактировать: В полезной нагрузке сообщения битового поля 0 или 1 для каждого фрагмента в торрент-файле, длина сообщения будет меняться в зависимости от размера содержимого торрента. Поэтому я не думаю, что могу предположить, что количество частей всегда будет соответствовать 5-байтовому числу.

Это было полезно?

Решение

Поле id всегда будет 5-м байтом сообщения после четырех байтов для поля len. Вы можете сделать что-то вроде следующего:

DataInputStream stream;

// ...

int    length  = stream.readInt();
byte   id      = stream.readByte();
byte[] payload = new byte[length - 1];

stream.readFully(payload);

На самом деле это должно работать для любого сообщения, поскольку все они имеют одинаковый заголовок <=> + <=>.

Edit: " поэтому я не думаю, что могу предположить, что количество частей всегда будет соответствовать 5-байтовому числу. "

Поле длиной в четыре байта может обрабатывать до 2 ^ 32-1 байтов в полезной нагрузке и с 8 битами на байт, что дает вам место для 34 359 738 360 штук. Этого должно быть много! : -)

Другие советы

  

Я не могу придумать способ разобрать его   если я не знаю длину;

Судя по описанию, длина указана в первых 4 байтах сообщения.

  

как я должен найти идентификатор в   поток байтов?

Похоже, что идентификатор является 5-м байтом в каждом сообщении, сразу после поля длины. Так что вам просто нужно посмотреть первые 5 байтов после того, как вы закончили анализ предыдущего сообщения.

Ранее в спецификации, на которую вы ссылались, я читал: « Префикс длины - это четырехбайтовое значение с прямым порядком байтов. ». Я прочитал это как: прочитайте следующие четыре байта, преобразовайте их в целое число, и это должно быть вашей длиной. Если вы не знакомы с процессом преобразования байтов в int, я использовал что-то похожее на это .

Я не читал спецификацию подробно, но без явного знания длины поля переменной длины или какого-либо ограничителя завершения, я не вижу, как вы можете обработать его. Возможно, bitfield=<len=0001+X> не означает, что вам сообщат о (переменной) длине заранее ?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top