我正在尝试在服务器/客户端反/序列化请求和响应。以下是我尝试过的内容:-
use std::collections::HashMap;
use std::fmt;
use std::io::prelude::*;
use std::net::TcpStream;
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct Address {
street: String,
city: String,
country: String,
}
#[derive(Serialize, Deserialize)]
enum Gender {
Male,
Female,
}
// #[derive(Debug)] does this internally.
impl fmt::Debug for Gender {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Gender::Male => write!(f, "M"),
Gender::Female => write!(f, "F"),
_ => write!(f, "U"),
}
}
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Hash)]
enum Level {
SSC,
HSC,
Graduation,
}
impl fmt::Debug for Level {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Level::SSC => write!(f, "SSC"),
Level::HSC => write!(f, "HSC"),
Level::Graduation => write!(f, "Graduation"),
_ => write!(f, "Unknown"),
}
}
}
#[derive(Serialize, Deserialize, Debug)]
struct Person {
ssn: String,
age: u16,
name: String,
gender: Gender,
contacts: Vec<String>,
address: Address,
education: HashMap<Level, i32>,
}
#[derive(Serialize, Deserialize, Debug)]
enum Message {
Request { ssn: String },
Response(Person),
Invalid,
}
fn handle_client(mut stream: TcpStream) {
// read data into buffer.
let mut buffer = Vec::new();
match stream.read_to_end(&mut buffer) {
Ok(n) => {
if n == 0 {
println!("connection closed!!!");
return;
}
let req = match serde_json::from_slice::<Message::Request>(&buffer) {
Ok(req) => {
println!("Received a valid request: {:?}", req);
req
}
Err(err) => {
let message = String::from_utf8_lossy(&buffer).to_string();
println!("Received an invalid message : {} ({})", message, err);
Message::Invalid
}
};
}
Err(err) => println!("error"),
}
}
这就是我卡住的地方(作为使用rust 的初学者)。谁能帮我找到反/序列化请求/响应的标准方法。
最佳答案
这是完整的示例,您可以在其中以二进制格式而不是序列化库发送数据。
这是来自服务器的 main.rs 文件。
use std::io::{ErrorKind, Read, Write};
use std::net::TcpListener;
use std::sync::mpsc;
use std::thread;
use std::thread::sleep;
use std::time::Duration;
const LOCAL: &str = "<type your server ip>:6000";
const MSG_SIZE: usize = 100;
fn main() {
let server = TcpListener::bind(LOCAL).expect("Listener failed to bind");
server.set_nonblocking(true).expect("failed to initialize non-blocking");
let mut clients = vec![];
let (tx, rx) = mpsc::channel::<String>();
loop {
if let Ok((mut socket, addr)) = server.accept() {
println!("Client {} connected", addr);
let tx = tx.clone();
clients.push(socket.try_clone().expect("failed to clone client"));
thread::spawn(move || loop {
let mut buff = vec![0; MSG_SIZE];
match socket.read_exact(&mut buff) {
Ok(_) => {
let msg = buff.into_iter().take_while(|&x| x != 0).collect::<Vec<_>>();
let msg = String::from_utf8(msg).expect("Invalid utf8 message");
println!("{}: {:?}", addr, msg);
tx.send(msg).expect("failed to send msg to rx");
},
Err(ref err) if err.kind() == ErrorKind::WouldBlock => (),
Err(_) => {
println!("closing connection with: {}", addr);
break;
}
}
});
}
if let Ok(msg) = rx.try_recv() {
clients = clients.into_iter().filter_map(|mut client| {
let mut buff = msg.clone().into_bytes();
buff.resize(MSG_SIZE, 0);
client.write_all(&buff).map(|_| client).ok()
}).collect::<Vec<_>>();
}
}
}
在服务器项目中,您还可以在Cargo.toml 文件中添加依赖。
[dependencies]
time = "0.1.42"
最后,这是客户端项目的main.rs。
use std::io::{self, ErrorKind, Read, Write};
use std::net::TcpStream;
use std::sync::mpsc::{self, TryRecvError};
use std::thread;
use std::time::Duration;
const LOCAL: &str = "<type your server ip>:6000";
const MSG_SIZE: usize = 100;
fn main() {
let mut client = TcpStream::connect(LOCAL).expect("Stream failed to connect");
client.set_nonblocking(true).expect("failed to initiate non-blocking");
let (tx, rx) = mpsc::channel::<String>();
thread::spawn(move || loop {
let mut buff = vec![0; MSG_SIZE];
match client.read_exact(&mut buff) {
Ok(_) => {
let msg = buff.into_iter().take_while(|&x| x != 0).collect::<Vec<_>>();
println!("message recv {:?}", msg);
},
Err(ref err) if err.kind() == ErrorKind::WouldBlock => (),
Err(_) => {
println!("connection with server was severed");
break;
}
}
match rx.try_recv() {
Ok(msg) => {
let mut buff = msg.clone().into_bytes();
buff.resize(MSG_SIZE, 0);
client.write_all(&buff).expect("writing to socket failed");
},
Err(TryRecvError::Empty) => (),
Err(TryRecvError::Disconnected) => break
}
thread::sleep(Duration::from_millis(100));
});
println!("Write a Message:");
loop {
let mut buff = String::new();
io::stdin().read_line(&mut buff).expect("reading from stdin failed");
let msg = buff.trim().to_string();
if msg == ":quit" || tx.send(msg).is_err() {break}
}
println!("bye bye!");
}
关于rust - 使用 rust serde 反序列化请求和响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57586624/