node.js 中的 UDP 跟踪器抓取意外返回零

Posted

技术标签:

【中文标题】node.js 中的 UDP 跟踪器抓取意外返回零【英文标题】:UDP tracker scrape in node.js returning zero unexpectedly 【发布时间】:2013-06-01 16:34:51 【问题描述】:

我正在尝试使用BitTorrent UDP Tracker Protocol 从公共 UDP 跟踪器(例如 tracker.publicbt.com 或 tracker.openbittorrent.com)执行 UDP 抓取。我的应用程序向跟踪器发送连接 ID 的请求,并使用该 ID 执行抓取。抓取响应从跟踪器返回,没有错误表明数据包格式错误,但无论我使用什么 info_hash,我都会返回“0”作为播种机、吸血机和已完成的数量。

我已经彻底检查了数据包的大小是否正确,info_hash 是否从正确的偏移量开始,并且数据是否正确。据我所知,创建和发送数据包没有问题。这个问题几天来一直没有答案,所以我更新并编辑了下面的代码示例,希望有人能提供帮助。

我已将 info_hash 硬编码到以下示例中。在命令行上运行时,此代码应连接到跟踪器,获取 connection_id,然后在 Ubuntu 种子信息哈希上执行抓取,将各种信息输出到控制台。

connection_id 被分成两部分,因为它是一个 64 位整数。

var dgram = require('dgram'),
    服务器 = dgram.createSocket("udp4"),
    连接IdHigh = 0x417,
    连接IdLow = 0x27101980,
    交易标识,
    行动,
    trackerHost = "tracker.publicbt.com",
    跟踪端口 = 80,
    infoHash = "",
    ACTION_CONNECT = 0,
    ACTION_ANNOUNCE = 1,
    ACTION_SCRAPE = 2,
    ACTION_ERROR = 3,
    sendPacket = function (buf, host, port) 
        “使用严格”;
        server.send(buf,0,buf.length,端口,主机,函数(错误,字节)
            如果(错误)
                控制台.log(err.message);
            
        );
    ,
    startConnection = 功能(主机,端口)
        “使用严格”;
        var buf = 新缓冲区(16);

        transactionId = Math.floor((Math.random()*100000)+1);

        buf.fill(0);

        buf.writeUInt32BE(connectionIdHigh, 0);
        buf.writeUInt32BE(connectionIdLow, 4);
        buf.writeUInt32BE(ACTION_CONNECT, 8);
        buf.writeUInt32BE(transactionId, 12);

        sendPacket(buf, 主机, 端口);
    ,
    scrapeTorrent = 函数(主机、端口、哈希)
        “使用严格”;
        var buf = 新缓冲区(56),
            tmp = '';

        infoHash = 哈希;

        如果(!transactionId)
            开始连接(主机,端口);
         别的 

            buf.fill(0);

            buf.writeUInt32BE(connectionIdHigh, 0);
            buf.writeUInt32BE(connectionIdLow, 4);
            buf.writeUInt32BE(ACTION_SCRAPE, 8);
            buf.writeUInt32BE(transactionId, 12);
            buf.write(infoHash, 16, buf.length);

            控制台.log(infoHash);
            console.log(buf.toString('utf8', 16, buf.length));

            // 进行刮擦
            sendPacket(buf, 主机, 端口);

            交易标识 = 空;
            信息哈希=空;
        

    ;

server.on("消息", function (msg, rinfo) 
    “使用严格”;
    var buf = 新缓冲区(味精),
        播种机,
        完全的,
        水蛭;

    控制台.log(rinfo);

    动作 = buf.readUInt32BE(0, 4);
    transactionId = buf.readUInt32BE(4, 4);

    console.log("返回的动作:" + action);
    console.log("返回的 transactionId:" + transactionId);

    如果(动作 === ACTION_CONNECT)
        console.log("连接响应");

        connectionIdHigh = buf.readUInt32BE(8, 4);
        connectionIdLow = buf.readUInt32BE(12, 4);

        scrapeTorrent(trackerHost, trackerPort, infoHash);

     else if (action === ACTION_SCRAPE) 
        console.log("抓取响应");

        播种机 = buf.readUInt32BE(8, 4);
        完成 = buf.readUInt32BE(12, 4);
        水蛭 = buf.readUInt32BE(16, 4);

        console.log(播种机);
        控制台.log(完成);
        console.log(leechers);

     else if (action === ACTION_ERROR) 
        console.log("错误响应");
    
);

server.on("监听", function () 
    “使用严格”;
    变量地址 = server.address();
    console.log("服务器监听" + address.address + ":" + address.port);
);

server.bind();

scrapeTorrent(trackerHost, trackerPort, "335990D615594B9BE409CCFEB95864E24EC702C7");

【问题讨论】:

我在上面添加了一个稍微改进的代码示例。在过去的几天里,我一直在尝试确定我创建缓冲区的方式是否有问题,但据我所知,这些字段都是正确的,包括 info_hash 部分。 【参考方案1】:

我终于解决了这个问题,并为自己没有早点意识到这一点而自责。

info_hash 是一个十六进制编码的字符串,所以当它被写入缓冲区时需要设置它的编码。例如:

buf.write(infoHash, 16, buf.length, 'hex');

UDP 跟踪器协议没有提及所需的编码,它只是将其描述为一个 20 字节的字符串。希望这个问答可以帮助遇到同样问题的其他人。

【讨论】:

以上是关于node.js 中的 UDP 跟踪器抓取意外返回零的主要内容,如果未能解决你的问题,请参考以下文章

python http/udp bittorrent 跟踪器抓取库

使用 node.js 抓取时使用 jQuery 访问 CSS 值

node.js 回调获取变量的意外值

UDP Tracker 在 PHP 中宣布

光流方法返回意外值

Node.JS:如何将变量传递给异步回调? [复制]