Непонимание того, как работает признак чтения для TcpStreams - PullRequest
0 голосов
/ 03 ноября 2019

Моя цель - прочитать несколько байтов из TcpStream, чтобы проанализировать данные в каждом сообщении и построить из него структуру.

loop {
    let mut buf: Vec<u8> = Vec::new();
    let len = stream.read(&mut buf)?;
    if 0 == len {
        //Disconnected
    }
    println!("read() -> {}", len);
}

Как и в Python, я думал, что stream.read() заблокируетпока не получил некоторые данные. Поэтому я настроил сервер, который вызывает цикл, который вы видите выше, для каждого входящего соединения. Затем я попытался подключиться к серверу с Netcat;netcat успешно подключается к серверу и блокирует на stream.read(), что я и хочу;но как только я отправлю некоторые данные, read() вернет 0. Я также пытался сделать что-то похожее с stream.read_to_end(), но, похоже, он возвращается только при закрытом соединении.

Как я могу читать из TcpStream сообщение за сообщение, зная, что каждое сообщение может иметьдругой, неизвестный, размер?

1 Ответ

2 голосов
/ 03 ноября 2019

Вы попадаете в штаны из-за технической сложности Vec больше, чем std::io::Read, хотя они оба взаимодействуют в данном конкретном случае.

Определение и документация Readсостояния:

Если возвращаемое значение этого метода - Ok (n), тогда должно быть гарантировано, что 0 <= n <= buf.len () </strong>. Ненулевое значение n указывает, что буферный буфер был заполнен n байтами данных из этого источника. Если n равно 0, то это может означать один из двух сценариев:

Важная часть выделена жирным шрифтом.

Когда вы определяете новый Vec, как вы это сделали, он запускаетсявместимостью ноль . Это означает, что базовый фрагмент (который вы будете использовать в качестве буфера) имеет нулевую длину. В результате, поскольку должно быть гарантировано, что 0 <= n <= buf.len() и buf.len() равно нулю, ваш вызов read() немедленно возвращается с 0 прочитанными байтами.

Чтобы "исправить" это, вы можете назначить либонабор элементов по умолчанию для вашего Vec (Vec::new().resize(1024, 0)), или просто используйте массив с самого начала (let mut buffer:[u8; 1024] = [0; 1024])

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...