javascript - 如何获得对 get_metadata 片段请求的响应? (node.js Bittorrent BEP 0009)

标签 javascript node.js protocols bittorrent torrent

我正在使用 Node.js 构建一个 Bittorrent 客户端,但无法通过 PWP 元数据扩展(BEP 0009)从同行那里获得答案

我从 DHT ( BEP 0005 )(我宣布的地方)获得对等点,然后使用网络套接字通过 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))
})

从这里,我得到握手和扩展的 Hanshake(有时还有位域),然后我需要元数据片段:

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 协议(protocol)消息格式。

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

<len><message>

len 是一个 UInt32 big endian,值为 message.length, 消息 是您要发送的任何内容,握手除外。

例如:

扩展协议(protocol)片请求:ut_metadata片消息

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

哪里:

  • len 是一个 UInt32 big endian of value: size of ()
  • Id 是一个值为 20 的 Uint8(它是协议(protocol)扩展指示符)
  • extId 是一个 UInt8。它的值(value)取决于 extended handshake从对端接收(其中给出了 ut_metadata 交换的 extId)
  • ut_metadata dict 是一个编码字典:

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

    d8:msg_typei0e5:piecei0ee

(第一行是对象 - 字典 - 第二行是编码后的同一个对象)

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

  • piece 是您请求的片段的索引(0 将是第一片段)

一般来说:

没有给 <len> 正确的值将导致消息被同伴错误地解释,因此得不到正确的答案,没有得到任何答案并最终关闭连接(由同伴或通过您自己的消息)

关于javascript - 如何获得对 get_metadata 片段请求的响应? (node.js Bittorrent BEP 0009),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41370143/

相关文章:

javascript - 创建翻滚指针动画

javascript - 如何强制 jQuery 向服务器发出 GET 请求以刷新缓存资源

javascript - 在 Node.js cli 中从 Dropbox 下载文件

javascript - 将 async.eachLimit 转换为 Promise

swift - 如何使用 Swift 协议(protocol)扩展来创建可以修改私有(private)属性的共享代码?

xcode - 如何在 Xcode 中自动实现协议(protocol)方法?

ruby - 使用 Ruby 创建二进制数据?

javascript - 如何修复 不要直接改变状态。将 setState() 与数组一起使用?

javascript - Node.js 监听模块加载

javascript - Knex 返回 DATETIME 字段,应用我的机器时区的偏移量