我正在尝试使用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会出现反序列化错误,提示存在无效字符。有更好的方法吗?
let input: Point3D = serde_json::from_reader(&stream)?;
,看起来它只是等待客户端的 EOF。我该如何让from_reader
在客户端发送特殊字符时退出? - ACCfrom_reader
在读取文件时会在遇到 EOF 时退出,EOF 是读取文件时的特殊字符。我想知道是否需要将换行符视为特殊字符,并在获取到换行符时使from_reader
返回。或者我对此有误解吗? - ACC.read_until
的用法,为什么在这里不适用呢? - Shepmasterread_until
让它工作了。感谢你的指引! - ACC