如何获得对ut_metadata片段请求的响应? (node.js Bit Torrent BEP 0009)

我正在使用Node.js构build一个Bittorrent客户端,并且无法通过PWP元数据扩展( BEP 0009 )

我从DHT( BEP 0005 )(我宣布)获得同行,然后使用networking套接字通过PWP发送Handshake和Extended Handshake。

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分钟后没有保持活着,连接超时。

有没有人知道我为什么不回答?

如果你是第一个计时器,BitTorrent协议消息格式化可能不清楚,就像我一样。

消息结构总是如下(握手除外):

 <len><message> 

其中len是一个UInt32的big endian值message.length, 消息是你发送的任何东西,除了握手。

举个例子:

扩展协议片请求:ut_metadata片消息

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

哪里:

  • len是一个有价值的UInt32大端:size()
  • Id是值20的Uint8(这是协议扩展指示符)
  • extId是一个UInt8。 它的价值取决于从对等体接收到的扩展握手 (其中给出了ut_metadata交换的扩展)
  • ut_metadata字典是一个bencoded字典:

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

    d8:msg_typei0e5:piecei0ee

(这里是第一行objet – 字典 – 第二行是同一个对象一次bencoded)

  • msg_type是0(这是BEP 0009请求的请求消息指示符。

  • 一块是你要求的一块的索引(0将是第一块)

一般来说:

没有给<len>赋予正确的值将导致消息严重地被对等解释,因此没有得到正确的答案,没有得到任何答案并且最终连接被closures(由同伴或通过你自己的消息)