Отправлять запросы DHT на router.bittorrent.com, искаженный текст ответа

Я прочитал протокол DHT на странице bep_0005.

Но когда я отправляю запрос ping или запрос find_node, сервер отвечает искаженным текстом (как router.bittorrent.com:6881, так и dht.transmissionbt.com:6881). )

Вот исходный код Java ниже

    public String ping(final String id) {
    System.out.println("Start ping:" + id);
    Bencode bencode = new Bencode();
    byte[] encoded = bencode.encode(new HashMap<Object, Object>() {
        private static final long serialVersionUID = 4225164001818744013L;

        {
            put("t", "tr");
            put("y", "q");
            put("q", "ping");
            put("a", new HashMap<Object, Object>() {
                private static final long serialVersionUID = -6092073963971093460L;

                {
                    put("id", id);
                }
            });
        }
    });
    byte[] result = client.send(new String(encoded, bencode.getCharset()));
    Map<String, Object> dict = bencode.decode(result, Type.DICTIONARY);
    System.out.println("Bdecoded Data:" + dict);
    return "";
}

Отправлять пакеты

ping Query = {"t":"aa", "y":"q", "q":"ping", "a":{"id":"abcdefghij0123456789"}}

bencoded = d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe

В соответствии с протоколом bep_0005 ответ будет таким:

Ответ = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}}

bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re

Но мой ответ:

Ответ = {ip=��P���, r={id=2�NisQ�J�)ͺ����F|�g}, t=tr, y=r}

bencoded = d2:ip6:��P���1:rd2:id20:2�NisQ�J�)ͺ����F|�ge1:t2:tr1:y1:re

Отправить код Java части udp:

    public byte[] send(String sendData) {
    DatagramSocket client;
    try {
        client = new DatagramSocket();
        client.setSoTimeout(5000);
        byte[] sendBuffer;
        sendBuffer = sendData.getBytes();
        InetAddress addr = InetAddress.getByName("router.bittorrent.com");
        int port = 6881;
        DatagramPacket sendPacket = new DatagramPacket(sendBuffer, sendBuffer.length, addr, port);
        client.send(sendPacket);
        byte[] receiveBuf = new byte[512];
        DatagramPacket receivePacket = new DatagramPacket(receiveBuf, receiveBuf.length);
        client.receive(receivePacket);
        System.out.println("Client Source Data:" + Arrays.toString(receivePacket.getData()));
        String receiveData = new String(receivePacket.getData(), "UTF-8");
        System.out.println("Client String Data:" + receiveData);
        client.close();
        return receivePacket.getData();
    } catch (SocketException e) {
        e.printStackTrace();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

прочитайте ответ в UTF-8 , но iso-8859-1 также является искаженным текстом.

кто может мне помочь, спасибо!


person fisheep    schedule 19.07.2017    source источник
comment
если вы хотите общаться с основным dht, вы можете использовать существующую библиотеку. он также содержит довольнопринтер для бенкодирования.   -  person the8472    schedule 21.07.2017


Ответы (2)


сервер отвечает искаженным текстом

Нет, ответ закодирован и содержит необработанные двоичные данные.
Он НЕ МОЖЕТ рассматриваться как текст.

В BEP5, чтобы сделать необработанный двоичный идентификатор node_id в примерах пригодным для печати, он был разумно выбран состоящим только из буквенно-цифровых символов.
См.:
Bittorrent KRPC - Почему идентификатор узла вдвое меньше info_hash и использовать каждый символ от а до я?

Ключ ip — это расширение, описанное в: BEP42 — расширение безопасности DHT.

Полученный ответ полностью действителен.

TODO: Working Java code
person Community    schedule 19.07.2017
comment
Спасибо за ваш ответ! если ответ нельзя рассматривать как текст, то как я могу получить информацию об ответе? получить значение ip и id? - person fisheep; 20.07.2017
comment
Извиняюсь! Не могу помочь вам с этим. Я не джаву. Попробуйте добавить к своему вопросу тег java. - person Encombe; 20.07.2017
comment
Также большое спасибо. Я добавил тег java. Можете ли вы добавить свой код языка разработки? это шестнадцатеричное декодирование верно? - person fisheep; 21.07.2017
comment
Возможно, это поможет: stackoverflow.com/questions/45043257/ - person Encombe; 21.07.2017

Map<String, Object> dict = bencode.decode(result, Type.DICTIONARY);

Это дает вам декодированный корневой словарь сообщения как Map. В нем вы должны найти словарь r как другую карту, и в этой карте значение id. Тип идентификатора будет зависеть от используемой вами библиотеки bedecoding.

Если это ByteBuffer или byte[], то у вас должно быть 20 байтов, которые вы можете закодировать в шестнадцатеричном формате (до 40 символов), если вам нужно, чтобы он был удобочитаемым. Протокол DHT работает с необработанными хэшами, а не с шестнадцатеричными значениями.

Если это String, вам придется преобразовать строку обратно в byte[] перед ее шестнадцатеричным кодированием. Это возможно только в том случае, если bdecoder использует для декодирования ISO 8859-1, потому что эта кодировка безопасна для двустороннего обмена, а utf-8 не предназначена для произвольных последовательностей байтов.

person the8472    schedule 26.07.2017
comment
спасибо! Я хочу знать, хочу ли я что-то сделать со значением id, нужно ли декодировать его в удобочитаемую строку? или я просто использую его в байте []? - person fisheep; 28.07.2017
comment
это, очевидно, зависит от того, что вы хотите с ним делать. - person the8472; 28.07.2017