2013-06-05 78 views
2

我试图从公共UDP跟踪器如tracker.publicbt.com或tracker.openbittorrent.com使用BitTorrent UDP Tracker Protocol执行UDP刮。我的应用程序向跟踪器发送了一个connection_id的请求,并使用该ID来执行刮擦。刮擦响应从追踪器返回,没有错误表明形成了严重的数据包,但无论我使用什么info_hash,我都会返回“0”表示播种器,扫描器和完成的数量。UDP跟踪器刮意外

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

我硬编码的info_hash到下面的例子。当在命令行上运行时,这段代码应该连接到跟踪器,获取一个connection_id,然后在Ubuntu的torrent上执行一次刷新info_hash,将各种信息输出到控制台。

的CONNECTION_ID被分成2份,因为它是一个64位的整数。

var dgram = require('dgram'), 
    server = dgram.createSocket("udp4"), 
    connectionIdHigh = 0x417, 
    connectionIdLow = 0x27101980, 
    transactionId, 
    action, 
    trackerHost = "tracker.publicbt.com", 
    trackerPort = 80, 
    infoHash = "", 
    ACTION_CONNECT = 0, 
    ACTION_ANNOUNCE = 1, 
    ACTION_SCRAPE = 2, 
    ACTION_ERROR = 3, 
    sendPacket = function (buf, host, port) { 
     "use strict"; 
     server.send(buf, 0, buf.length, port, host, function(err, bytes) { 
      if (err) { 
       console.log(err.message); 
      } 
     }); 
    }, 
    startConnection = function (host, port) { 
     "use strict"; 
     var buf = new Buffer(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, host, port); 
    }, 
    scrapeTorrent = function (host, port, hash) { 
     "use strict"; 
     var buf = new Buffer(56), 
      tmp = ''; 

     infoHash = hash; 

     if (!transactionId) { 
      startConnection(host, port); 
     } else { 

      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); 

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

      // do scrape 
      sendPacket(buf, host, port); 

      transactionId = null; 
      infoHash = null; 
     } 

    }; 

server.on("message", function (msg, rinfo) { 
    "use strict"; 
    var buf = new Buffer(msg), 
     seeders, 
     completed, 
     leechers; 

    console.log(rinfo); 

    action = buf.readUInt32BE(0, 4); 
    transactionId = buf.readUInt32BE(4, 4); 

    console.log("returned action: " + action); 
    console.log("returned transactionId: " + transactionId); 

    if (action === ACTION_CONNECT) { 
     console.log("connect response"); 

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

     scrapeTorrent(trackerHost, trackerPort, infoHash); 

    } else if (action === ACTION_SCRAPE) { 
     console.log("scrape response"); 

     seeders = buf.readUInt32BE(8, 4); 
     completed = buf.readUInt32BE(12, 4); 
     leechers = buf.readUInt32BE(16, 4); 

     console.log(seeders); 
     console.log(completed); 
     console.log(leechers); 

    } else if (action === ACTION_ERROR) { 
     console.log("error response"); 
    } 
}); 

server.on("listening", function() { 
    "use strict"; 
    var address = server.address(); 
    console.log("server listening " + address.address + ":" + address.port); 
}); 

server.bind(); 

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

我已经添加上方的轻微改善的代码示例。在过去的几天我一直在试图确定是否有什么问题我创建了缓冲区的方式,但据我可以告诉领域是正确的,包括info_hash部分。 – Pappa

回答

4

我终于解决了这个问题,并且因为没有及时实现,

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

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

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