有BitTorrent协议的问题

我正在尝试为一个学校项目做一个简单的BitTorrent跟踪器。 它现在完全被黑了,但我无法find我要去哪里错了。 我想知道我是否对服务器响应应该有什么误解。 我正在使用node.js和expression。

服务器接收/ GET请求与?info_hash数据没有问题。 而且我可以将这些信息保存到JSON文件中。 服务器也能够使用本码编码来响应客户端。 答案是有一个间隔和一个同龄人列表的字典。 列表中有几个字典,每个字典都包含对等体的IP和端口。

目前,虽然没有一个同行会互相连接。 我将把我的笔记本电脑放在与我的桌面不同的networking上,并且将桌面视为一个潜在的对等点,正确的IP和端口(据我所知),但过了一会儿,它就从对等列表中删除。 我在每个客户端上使用deluge和qBitTorrent。

这里是应用程序的代码:

var express = require('express'); var app = express(); var fs = require("fs"); var contents = fs.readFileSync("data.json"); var data = JSON.parse(contents); var findTorrent = function(data, hash) { for(var i = 0; i < data.length; i++) { if(data[i].info_hash === hash) { return data[i]; } } return false; } var findID = function(data, qPort, qip) { for(var i = 0; i < data.length; i++) { //console.log(data[i].peer_id); if(data[i].port == qPort && data[i].ip === qip) { return true; } } return false; } var findHash = function(data, id) { for(var i = 0; i < data.length; i++) { if(data[i].peer_id === id) { return data[i]; } } return false; } function hashy (str) { var url = str; var hexval = ''; for(var i = 0; i < url.length; i++) { if(url[i] !== '%') { var code = url.charCodeAt(i); var hex = code.toString(16); hexval += hex; } else { hexval += url[i+1] + url[i+2]; i += 2; } } return hexval; } app.get('/', function(req, res) { console.log(req.query); var info_hash = hashy(req.query.info_hash); console.log(info_hash); var peer_id = decodeURIComponent(req.query.peer_id); var escaped = escape(req.query.peer_id); console.log('escaped ' + escaped); console.log('decoded ' + peer_id); console.log('normal ' + req.query.peer_id); var ip = req.connection.remoteAddress; if(ip.substring(0,7) == '::ffff:') { ip = ip.substring(7); } //var port = req.connection.remotePort; var port = req.query.port; console.log(ip); var torrent = findTorrent(data, info_hash); var completed; if (torrent === false){ if(req.query.left === '0') { completed = true; } else { completed = false; } var obj = { "info_hash" : info_hash, "peers" : [{ "peer_id" : peer_id, "ip" : ip, "port" : port, "completed" : completed }]}; data.push(obj); torrent = obj; //console.log(obj.peers); } else { //figure out if completed if(req.query.left == '0') { completed = true; } else { completed = false; } var peer = findHash(torrent.peers, peer_id); if(peer === false){ var obj = { "peer_id" : peer_id, "ip" : ip, "port" : port, "completed" : completed }; torrent.peers.push(obj); } else { peer.ip = ip; peer.port = port; peer.completed = completed; } } if(torrent) { var response = bencode(torrent); } else { response = 'error'; } //console.log(data); fs.writeFileSync("data.json", JSON.stringify(data, null, 2), 'utf-8'); res.send(response); }); var bencode = function(torrent) { var response = 'd8:intervali600e12:min intervali30e' var complete = 0; var incomplete = 0; for(var i = 0; i < torrent.peers.length; i++) { if(torrent.peers[i].completed === true) { complete++; } else { incomplete++; } } var response = response.concat('8:completei' + complete + 'e'); var response = response.concat('10:incompletei' + incomplete + 'e5:peersl'); for(var i = 0; i < torrent.peers.length; i++) { response = response.concat('d'); response = response.concat('2:ip'); response = response.concat(torrent.peers[i].ip.length + ':'); response = response.concat(torrent.peers[i].ip); //response = response.concat('7:peer id'); //response = response.concat(torrent.peers[i].peer_id.length + ':'); //response = response.concat(torrent.peers[i].peer_id); response = response.concat('4:port'); response = response.concat('i' + torrent.peers[i].port + 'e'); response = response.concat('e'); } response = response.concat('ee'); console.log(response); return response; } app.listen(4000, function() { console.log('Example app listening on port 4000!'); }); 

我可以连接到Amazon AWS上托pipe的跟踪器,qBitTorrent将其报告为“正在工作”。 我也可以看到GET请求和服务器响应通过wireshark进来。 请求有以下bencodedstring,我相信是所有必要的:

 d8:intervali600e12:min intervali30e8:completei2e10:incompletei3e5:peersld2:ip13:73.66.138.2174:porti8999eed2:ip13:73.66.138.2174:porti63014eed2:ip13:73.66.138.2174:porti8999eed2:ip13:73.25.106.1804:porti6881eed2:ip13:73.66.249.1414:porti8999eeee 

据www.bittorrent.org所说,响应中所需要的只是一个间隔,一个对等列表映射到对等列表。 每个对等体需要id,ip和端口。

我已经将端口切换到客户端在请求中报告的端口,并确保我的torrent客户端有端口转发,现在似乎工作。 虽然我仍然要继续这个工作。 目前,我们没有办法在停止播种/榨取时将同伴移除。

这似乎主要是同行之间而不是追踪者之间的问题。 如果它们都是NAT的,至less它们中的一个需要通过NAT转发端口,以便它们能够相互连接。

跟踪器响应中的端口应该是对等方在请求中报告的端口。

跟踪器响应中的代码字典不是sorting的, 按键 complete, incomplete, interval, min interval, peers顺序应该按原始stringsorting。
有些客户如果不是,可能会有问题。

另一件事是,在BEP3中指定的跟踪器响应,虽然仍然正确,但已经被compact = 1响应所淘汰。 所有现代客户都支持“紧凑”。 虽然我不知道有任何客户已经放弃了对传统方式的支持,但一些追踪者已经有了。
布拉姆·科恩(Bram Cohen)曾经说过: “对'紧凑'的延伸的不支持被认为是现在的彻头彻尾的不良行为。” post#5

有关BitTorrent协议的好资源是https://wiki.theory.org/BitTorrentSpecification

这个答案是作为评论张贴原始的一个编辑版本。

请注意不要在跟踪器响应中返回尾部回车。 这使得编码响应无效,有些客户不喜欢它。

    Interesting Posts