3

BitTorrent UDP Tracker Protocolを使用して、tracker.publicbt.com や tracker.openbittorrent.com などのパブリック UDP トラッカーから UDP スクレイピングを実行しようとしています。私のアプリは、トラッカーに connection_id のリクエストを送信し、その ID を使用してスクレイプを実行します。スクレイプ応答はトラッカーから返され、パケットの形式が正しくないことを示すエラーはありませんが、使用する info_hash に関係なく、シーダー、リーチャー、および完了の数に対して「0」が返されます。

パケットが適切なサイズであること、info_hash が正しいオフセットから開始すること、データがすべて正しいことを徹底的にチェックしました。私が見る限り、パケットの作成と送信に問題はありません。この質問は数日間開かれており、回答が得られていないため、誰かが助けてくれることを期待して、以下のコード例を更新および編集しました.

次の例では、info_hash をハードコーディングしました。コマンド ラインで実行すると、このコードはトラッカーに接続し、connection_id を取得してから、Ubuntu torrent info_hash でスクレイプを実行し、さまざまな情報をコンソールに出力します。

connection_id は 64 ビット整数であるため、2 つの部分に分割されます。

var dgram = require('dgram'),
    サーバー = dgram.createSocket("udp4"),
    connectionIdHigh = 0x417、
    connectionIdLow = 0x27101980、
    取引ID、
    アクション、
    trackerHost = "tracker.publicbt.com",
    トラッカーポート = 80、
    infoHash = "",
    ACTION_CONNECT = 0、
    ACTION_ANNOUNCE = 1、
    ACTION_SCRAPE = 2、
    ACTION_ERROR = 3、
    sendPacket = 関数 (バッファ、ホスト、ポート) {
        "厳密を使用";
        server.send(buf, 0, buf.length, port, host, function(err, bytes) {
            もし (エラー) {
                console.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 = ハッシュ;

        if (!transactionId) {
            startConnection(ホスト、ポート);
        } そうしないと {

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

            // スクレイピングする
            sendPacket (buf、ホスト、ポート);

            transactionId = null;
            infoHash = null;
        }

    };

server.on("メッセージ", 関数 (msg, rinfo) {
    "厳密を使用";
    var buf = new Buffer(msg),
        シーダー、
        完了、
        リーチャー;

    console.log(rinfo);

    アクション = buf.readUInt32BE(0, 4);
    transactionId = buf.readUInt32BE(4, 4);

    console.log("返されたアクション: " + アクション);
    console.log("返された transactionId: " + transactionId);

    if (アクション === ACTION_CONNECT) {
        console.log("接続応答");

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

        スクレイプトレント(トラッカーホスト、トラッカーポート、インフォハッシュ);

    } それ以外の場合 (アクション === ACTION_SCRAPE) {
        console.log("スクレイプ応答");

        シーダー = buf.readUInt32BE(8, 4);
        完了 = buf.readUInt32BE(12, 4);
        リーチャー = buf.readUInt32BE(16, 4);

        console.log(シーダー);
        console.log(完了);
        console.log(リーチャー);

    } その他の場合 (アクション === ACTION_ERROR) {
        console.log("エラー応答");
    }
});

server.on("リスニング", function () {
    "厳密を使用";
    var アドレス = server.address();
    console.log("サーバーのリッスン" + address.address + ":" + address.port);
});

サーバー.バインド();

ScrapeTorrent(trackerHost, trackerPort, "335990D615594B9BE409CCFEB95864E24EC702C7");
4

1 に答える 1

5

私はついにこれを解決し、すぐに気付かなかったことに自分自身を蹴りました。

info_hash は 16 進数でエンコードされた文字列であるため、バッファーに書き込むときにエンコードを設定する必要があります。例えば:

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

UDP トラッカー プロトコルでは、必要なエンコードについては言及されておらず、20 バイトの文字列として記述されているだけです。この Q&A が、同じ問題に遭遇した他の誰かの助けになることを願っています。

于 2013-06-10T06:53:28.243 に答える