Если ваша цель на самом деле получить один пакет, я думаю, что вы добились успеха!
Я несколько раз тестировал программу и получал ответ.Я тестирую с:
nc 127.0.0.1 8080 <<< hello
После нескольких попыток я получаю следующий вывод:
Listening on: 0.0.0.0:8080
bytes: [104, 101, 108, 108, 111, 10]
bytes: []
bytes: [104, 101, 108, 108, 111, 10]
bytes: []
bytes: [104, 101, 108, 108, 111, 10]
bytes: []
bytes: [104, 101, 108, 108, 111, 10]
bytes: [104, 101, 108, 108, 111, 10]
Как видите, иногда у нас есть данные, готовые, а иногдамы неЯ думаю, что в вашем тестировании вам просто не повезло, и вы получили ответы TCP только до того, как были отправлены какие-либо данные?
Я примерно на 90% уверен, что потоки TCP могут содержать пустые пакеты, и это то, что мы "видишь.(если у кого-то есть больше знаний здесь, не стесняйтесь редактировать ответ или комментарий).
Чтобы исправить вашу программу, вы можете пересмотреть свою цель.
Кажется, что чтение одного TCP-пакетаредко помогает.Вместо этого, как правило, вы хотите прочитать некоторое количество байтов и обрабатывать данные по мере их поступления.Мое понимание TCP - это поток байтов, а не поток пакетов.Пакеты - это просто способ передачи байтов из одного места в другое, и они могут быть любой длины без нарушения совместимости.«Один пакет» является довольно туманным понятием.
Вот пример чтения первых 16 байтов потока с использованием функции tokio::io::read_exact
:
extern crate tokio;
use tokio::net::TcpListener;
use tokio::prelude::*;
use std::net::SocketAddr;
fn main() {
let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
let socket = TcpListener::bind(&addr).unwrap();
println!("Listening on: {}", addr);
let done = socket
.incoming()
.map_err(|e| println!("failed to accept socket; error = {:?}", e))
.for_each(move |mut socket| {
// this function deals with bytes a bit differently and will just fill the
// buffer exactly rather than adding onto the end.
let mut bytes = vec![0; 16];
let processor = tokio::io::read_exact(socket, bytes)
.and_then(move |(socket, bytes)| {
println!("bytes: {:?}", bytes);
Ok(())
})
.map_err(|_| ());
tokio::spawn(processor)
});
tokio::run(done);
}