Кодировать utf8 на TcpStream

Я пытаюсь направить весь свой трафик с помощью Iptables.

iptables -t nat -D OUTPUT -p tcp -j DNAT --to-destination 127.0.0.1:3400

к моему коду Rust, который прослушивает определенный порт

    let addrs = [
        SocketAddr::from(([127, 0, 0, 1], 3400)),
    ];
    let tcp = TcpListener::bind(&addrs[..]).expect("error bind tcp");
    match tcp.accept() {
        Ok((_socket,addr)) => println!("{:?} ",addr),
        Err(_) => println!("error found"),
    }
    let mut buffer = [0;500];
    let mut buf = unsafe {
        slice::from_raw_parts_mut((&mut buffer).as_mut_ptr(),buffer.len())
    };
    for stream in tcp.incoming() {
        let buf = stream.unwrap().read(buf).expect("stream read buffer ");
        let result = StrType::from_utf8(&buffer).expect("result decode failed");
        // println!("{:?} {:?}",buffer,buf);
        println!("{:?}",buf);
        println!("{}",result.len());
        println!("{:?}\n\n",result);
    }

затем я хочу прочитать свои данные, которые UTF8, и я столкнулся с такой ошибкой.

thread 'main' panicked at 'result decode failed: Utf8Error { valid_up_to: 8, error_len: Some(1) }', src/main.rs:46:50

Как я могу устранить эту ошибку или как я могу получить запрошенные данные?

Спасибо за вашу помощь.

Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
0
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку символы строк в кодировке utf8 могут иметь длину от 1 до 4 байтов, когда вы получаете передачу по сети (или другим потоковым способом), может случиться так, что этот пакет (или буфер, в который вы читаете) разделен посередине персонажа. Rust требует, чтобы типы str и String содержали только допустимые символы в кодировке utf8, поэтому, когда вы пытаетесь интерпретировать байты как строку utf8, он возвращает ошибку.

К счастью, этот тип ошибки Utf8Error содержит информацию о том, до какого байта этот фрагмент байта действителен utf8. Таким образом, вы можете использовать только первую правильную часть, а остальные объединять с другими данными. Вы можете увидеть пример этого в связанной документации.

Кроме того, вам не нужно использовать небезопасный slice::from_raw_parts_mut, просто используйте &mut buffer.

Спасибо за эту документацию. Например, если я буду запрашивать разрешение DNS в своем коде с помощью этого кода, как можно проанализировать запрос с помощью нечитаемого UTF8? Теперь я могу прочитать первые символы в моем запросе для HTTP, но другие запросы все еще доступны для чтения.

mwg 20.10.2022 19:15

@mwg DNS не является текстовым протоколом. Вы должны анализировать байты как байты, а не как строку UTF8.

justinas 20.10.2022 21:36

@justinas, тогда как можно не анализировать байты как байты с помощью Rust?

mwg 20.10.2022 23:08

@mwg вы бы прочитали пакет DNS в массив байтов, как сейчас. Отличие в том, что вы не будете преобразовывать его в строку, а будете работать с самими байтами в соответствии с протоколом. Также, похоже, существуют ящики, такие как dns_parser, чтобы помочь с этим.

justinas 21.10.2022 14:52

@justinas, кажется, это мой ответ. :)

mwg 23.10.2022 05:28

Другие вопросы по теме