2016-12-28 1 views
4

Я строю клиент Bittorrent с помощью Node.js и терплю неудачу в получении ответа от сверстников над расширением PWP метаданных (BEP 0009)Как получить ответы на запрос части ut_metadata? (Node.js Bit Torrent BEP 0009)

я получаю сверстникам из DHT (BEP 0005) (где я объявляю), затем отправьте Handshake и Extended Handshake поверх PWP с помощью сетевого гнезда.

buildHandshake = (torrent, ext) => { // torrent contains mainly infoHash 
    const buf = Buffer.alloc(68) 
    buf.writeUInt8(19, 0) 
    buf.write('BitTorrent protocol', 1) 
    if (ext) { 
     const big = new Uint64BE(1048576) 
     big.toBuffer().copy(buf, 20) 
    } else { 
     buf.writeUInt32BE(0, 20) 
     buf.writeUInt32BE(0, 24) 
    } 
    torrent.infoHashBuffer.copy(buf, 28) 
    anon.nodeId().copy(buf, 48) // tool that generates a nodeId once. 
    return buf 
} 

buildExtRequest = (id, msg) => { 
    const size = msg.length + 1 
    const buf = Buffer.alloc(size + 5) 
    buf.writeUInt32BE(size, 0) 
    buf.writeUInt8(20, 4) 
    buf.writeUInt8(id, 5) 
    msg.copy(buf, 6) 
    return buf 
} 

const client = new net.Socket() 
    client.connect(peer.port, peer.ip,() => { 
     client.write(buildHandshake(torrent, true)) 
     const extHandshake = bencode.encode({ 
      m: { 
       ut_metadata: 2, 
      }, 
      metadata_size: self.metaDataSize, // 0 by default 
      p: client.localPort, 
      v: Buffer.from('Hypertube 0.1') 
     }) 
     client.write(buildExtRequest(0, extHandshake)) 
}) 

Отсюда, я получаю Рукопожатия и расширенные Hanshakes назад (а иногда Битовые поля), то я требуют части метаданных:

const req = bencode.encode({ msg_type: 0, piece: 0 }) 

// utMetadata is from extended Handshake dictionary m.ut_metadata 
client.write(message.buildExtRequest(utMetadata, req)) 

После чего, я не слышал от сверстников больше. После 2 минут без сохранения времени ожидания соединения.

У кого-нибудь есть идея, почему я не получаю ответа?

+0

Вы пытались использовать WireShark и сравнить с рабочим клиентом? – Encombe

+0

будет полезен hexdump вашего и их сообщений – the8472

+2

Я работал над Wireshark и выяснил, в чем проблема: bencode.encode будет кодировать ключ без значения, если значение не определено, и не будет бросать ошибку. Это и странно, префикс длины отсутствовал один байт, превращая следующие сообщения в не расширенные, а скорее _interested_ или _unchoke_, неправильно сформированные, в результате чего сверстник закрывается. –

ответ

1

Форматирование сообщения протокола BitTorrent может быть неясным, если вы первый таймер, как и я.

структура сообщения всегда следующим образом (за исключением рукопожатия):

<len><message> 

где Len является UInt32 больших байтами стоимостного message.length, сообщения является то, что вы посылаете, кроме рукопожатия ,

Для Exemple:

Расширенной запрос протокола части: ut_metadata части сообщения

<len><id><extId><ut_metadata dict> 

где:

  • Len является UInt32 больших байтами значения: размер()
  • Id является Uint8 значения 20 (это индикатор расширения протокола)
  • extId является UInt8. Его величина зависит от extended handshake полученной от партнера (в которой extId из ut_metadata обмена дан)
  • ut_metadata ДИКТ является bencoded словарь:

    { 'msg_type': 0, 'piece': 0 }

    d8:msg_typei0e5:piecei0ee

(здесь на первой строке объект - словарь - а на второй строке это то же самое Ct раз bencoded)

  • MSG_TYPE является 0 (это индикатор запроса сообщения для запроса BEP 0009 шт.

  • кусок является индекс поштучно вы запрашиваете (0 будет первая часть)

В общем:

Не давая правильное значение для <len> приведет к сообщениям плохо интерпретируется экспертом и, следовательно, не получает правильных ответов, не получает ответа и, в конечном счете, закрывается (со стороны сверстников или через ваши собственные сообщения)

Смежные вопросы