Десериализация JSON с разделителями новой строки из сокета с использованием Serde

Abhishek Chanda спросил: 13 октября 2017 в 07:48 в: rust

Я пытаюсь использовать serde для отправки структуры JSON с клиента на сервер. Новая строка от клиента к серверу отмечает, что сокет завершен. Мой сервер выглядит следующим образом

#[derive(Serialize, Deserialize, Debug)]
struct Point3D {
    x: u32,
    y: u32,
    z: u32,
}fn handle_client(mut stream: TcpStream) -> Result<(), Error> {
    println!("Incoming connection from: {}", stream.peer_addr()?);
    let mut buffer = [0; 512];
    loop {
        let bytes_read = stream.read(&mut buffer)?;
        if bytes_read == 0 {
            return Ok(());
        }
        let buf_str: &str = str::from_utf8(&buffer).expect("Boom");
        let input: Point3D = serde_json::from_str(&buf_str)?;
        let result: String = (input.x.pow(2) + input.y.pow(2) + input.z.pow(2)).to_string();
        stream.write(result.as_bytes())?;
    }
}fn main() {
    let args: Vec<_> = env::args().collect();
    if args.len() != 2 {
        eprintln!("Please provide --client or --server as argument");
        std::process::exit(1);
    }
    if args[1] == "--server" {
        let listener = TcpListener::bind("0.0.0.0:8888").expect("Could not bind");
        for stream in listener.incoming() {
            match stream {
                Err(e) => eprintln!("failed: {}", e),
                Ok(stream) => {
                    thread::spawn(move || {
                        handle_client(stream).unwrap_or_else(|error| eprintln!("{:?}", error));
                    });
                }
            }
        }
    } else if args[1] == "--client" {
        let mut stream = TcpStream::connect("127.0.0.1:8888").expect("Could not connect to server");
        println!("Please provide a 3D point as three comma separated integers");
        loop {
            let mut input = String::new();
            let mut buffer: Vec<u8> = Vec::new();
            stdin()
                .read_line(&mut input)
                .expect("Failed to read from stdin");
            let parts: Vec<&str> = input.trim_matches('\n').split(',').collect();
            let point = Point3D {
                x: parts[0].parse().unwrap(),
                y: parts[1].parse().unwrap(),
                z: parts[2].parse().unwrap(),
            };
            stream
                .write(serde_json::to_string(&point).unwrap().as_bytes())
                .expect("Failed to write to server");            let mut reader = BufReader::new(&stream);            reader
                .read_until(b'\n', &mut buffer)
                .expect("Could not read into buffer");
            print!(
                "{}",
                str::from_utf8(&buffer).expect("Could not write buffer as string")
            );
        }
    }
}

Как узнать, какой размер буфера нужно выделить перед чтением в строке? Если мой буфер слишком велик, serde не сможет десериализовать его из-за ошибки, указывающей на наличие недопустимых символов. Есть ли лучший способ сделать это?

0 ответов