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

Javascript node.js中的UDP跟踪器刮取意外返回零,javascript,node.js,udp,bittorrent,Javascript,Node.js,Udp,Bittorrent,我正在尝试使用从公共UDP跟踪器(如tracker.publicbt.com或tracker.openbittorrent.com)执行UDP刮取。我的应用程序向追踪器发送连接id请求,并使用该id执行刮取。scrape响应是从跟踪器返回的,没有错误来指示格式错误的数据包,但是无论我使用什么信息散列,对于播种机、leechers和completed的数量,我都会返回“0” 我已经彻底检查了数据包的大小是否正确,信息散列是否从正确的偏移量开始,数据是否都正确。就我所见,创建和发送数据包没有问题。这

我正在尝试使用从公共UDP跟踪器(如tracker.publicbt.com或tracker.openbittorrent.com)执行UDP刮取。我的应用程序向追踪器发送连接id请求,并使用该id执行刮取。scrape响应是从跟踪器返回的,没有错误来指示格式错误的数据包,但是无论我使用什么信息散列,对于播种机、leechers和completed的数量,我都会返回“0”

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

我已经在下面的示例中硬编码了一个info_散列。在命令行上运行时,此代码应连接到跟踪器,获取连接id,然后在Ubuntu torrent info散列上执行刮取,将各种信息位输出到控制台

连接id分为两部分,因为它是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"); var dgram=require('dgram'), server=dgram.createSocket(“udp4”), connectionIdHigh=0x417, connectionIdLow=0x27101980, 事务ID, 行动, trackerHost=“tracker.publicbt.com”, trackerPort=80, infoHash=“”, 动作连接=0, 行动宣布=1, 动作_刮取=2, 动作错误=3, sendPacket=功能(buf、主机、端口){ “严格使用”; 发送(buf,0,buf.length,端口,主机,函数(err,字节){ 如果(错误){ 控制台日志(错误消息); } }); }, startConnection=功能(主机、端口){ “严格使用”; var buf=新缓冲区(16); transactionId=Math.floor((Math.random()*100000)+1); buf.填充(0); buf.writeUInt32BE(connectionIdHigh,0); buf.writeUInt32BE(connectionIdLow,4); buf.writeUInt32BE(动作连接,8); buf.writeUInt32BE(交易ID,12); 发送包(buf、主机、端口); }, scrapeTorrent=函数(主机、端口、哈希){ “严格使用”; var buf=新缓冲器(56), tmp=''; infoHash=hash; 如果(!transactionId){ startConnection(主机、端口); }否则{ buf.填充(0); buf.writeUInt32BE(connectionIdHigh,0); buf.writeUInt32BE(connectionIdLow,4); buf.writeUInt32BE(行动8); buf.writeUInt32BE(交易ID,12); buf.write(infoHash,16,buf.length); log(infoHash); 日志(buf.toString('utf8',16,buf.length)); //刮 发送包(buf、主机、端口); transactionId=null; infoHash=null; } }; 打开(“消息”,函数(msg,rinfo){ “严格使用”; var buf=新缓冲区(msg), 播种机, 完整的, 利切; 控制台日志(rinfo); 动作=buf.readUInt32BE(0,4); transactionId=buf.readUInt32BE(4,4); log(“返回的操作:+action”); log(“返回的transactionId:+transactionId”); 如果(动作===动作连接){ 日志(“连接响应”); connectionIdHigh=buf.readUInt32BE(8,4); connectionIdLow=buf.readUInt32BE(12,4); scrapeTorrent(trackerHost、trackerPort、infoHash); }否则如果(动作===动作\u刮取){ 控制台日志(“刮取响应”); 播种机=buf.readUInt32BE(8,4); 已完成=基本读数32BE(12,4); leechers=buf.readUInt32BE(16,4); 控制台。原木(播种机); 控制台日志(已完成); 控制台日志(leechers); }else if(action==action\u错误){ console.log(“错误响应”); } }); server.on(“侦听”,函数(){ “严格使用”; var address=server.address(); log(“服务器侦听”+address.address+”:“+address.port”); }); bind();
scrapeTorrent(trackerHost,trackerPort,“335990D615594B9BE409CCFEB95864E24EC702C7”) 我终于明白了这一点,并责备自己没有早点意识到这一点

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

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

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

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