gpt4 book ai didi

rust - 使用 Serde 从套接字反序列化以换行符分隔的 JSON

转载 作者:行者123 更新时间:2023-11-29 07:59:37 25 4
gpt4 key购买 nike

我正在尝试使用 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 将无法反序列化它,并出现错误,指出存在无效字符。有更好的方法吗?

最佳答案

TcpStream 放入 BufReader。这允许您读取到特定字节(在本例中为换行符)。然后您可以使用 Serde 解析读取的字节:

use std::io::{BufRead, BufReader};
use std::io::Write;

fn handle_client(mut stream: TcpStream) -> Result<(), Error> {
let mut data = Vec::new();
let mut stream = BufReader::new(stream);

loop {
data.clear();

let bytes_read = stream.read_until(b'\n', &mut data)?;
if bytes_read == 0 {
return Ok(());
}

let input: Point3D = serde_json::from_slice(&data)?;
let value = input.x.pow(2) + input.y.pow(2) + input.z.pow(2);

write!(stream.get_mut(), "{}", value)?;
}
}

我对重用data 的分配有点异想天开,这意味着在每个循环开始时重置缓冲区非常重要。我还避免为结果分配内存,而是直接打印到输出流。

关于rust - 使用 Serde 从套接字反序列化以换行符分隔的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47146114/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com