发生错误时,正确的循环方式是什么



我对Rust还很陌生,我仍在努力确保我理解在一个小项目中创建使用TcpStream的服务器的原则。服务器向客户端请求一个必须为8个字符长的代码。如果没有,它将再次要求一个新的代码。以下是我目前所拥有的:


fn loby_matcher(stream: &mut TcpStream) -> std::io::Result<(String, usize), >{
let mut game_code = String::new();
let mut reader = BufReader::new(stream);
let len : usize = reader.read_line(&mut game_code)?;
match len {
8 => len,
_ => return Err(Error::new(ErrorKind::Other, "wrong game code")),
};
Ok((game_code, len))
}
pub fn create_game_matcher(mut stream: TcpStream) -> std::io::Result<()>{
println!("Creating a new game! Waiting for the code.");
let game_code: String;
let len: usize;
loop {
(game_code, len) = match loby_matcher(&mut stream) {
Ok(game_code) => break (game_code, len),
Err(e) => {
stream.write("Wrong coden".as_bytes());
(String::new(),0)
}
};
};
println!("Received : {} size {}", game_code, len);
// println!("Closing connection now I guess?");
Ok(())
}
fn start_server(address: &str, port: &str) -> std::io::Result<()>{
let listener = TcpListener::bind(format!("{}:{}", address, port))?;
for stream in listener.incoming() {
// not using ? as we do not want to stop the server for wrong connection
let stream = stream.unwrap(); 
thread::spawn(move || {
create_game_matcher(stream);
});
}
Ok(())
}

当出现错误时,请求新代码的循环似乎是错误的,但我无法找到实现这一点的方法。此外,我知道我应该创建一个自定义错误,以便能够在我的TCPstream上区分错误代码和I/O错误,我稍后会这样做。当发生特定错误时,正确的循环方式是什么?

编辑

如果你在代码中看到任何错误,请毫不犹豫地告诉我如何改进它。

我假设您正在询问如何解决create_game_matcher中的问题。如果是这样的话,那么你就需要把你的任务移得更远。

要比较io::Error内部的错误,可能会很麻烦。您可以使用e.kind() == ErrorKind::Other检查种类。然而,实际的错误可能是任何错误,并且不需要为&str实现PartialEq。最简单的可能就是做e.to_string() == "wrong game code"

但正如您所提到的,最惯用的方法是创建自己的错误类型。

pub fn create_game_matcher(mut stream: TcpStream) -> std::io::Result<()> {
println!("Creating a new game! Waiting for the code.");
let (game_code, len) = loop {
match loby_matcher(&mut stream) {
Ok(game_code) => break game_code,
// Err(e) if e.kind() == ErrorKind::Other && e.to_string() == "wrong game code" => {
// or just (for ease of use)
Err(e) if e.to_string() == "wrong game code" => {
stream.write("Wrong coden".as_bytes())?;
}
Err(e) => return Err(e),
};
};
println!("Received : {} size {}", game_code, len);
// println!("Closing connection now I guess?");
Ok(())
}

由于要循环直到loby_matcher成功,因此可以删除(String::new(), 0)。您还忘记检查stream.write是否失败,所以我添加了一个?


或者,如果你总是在分配后中断,你也可以这样表达:

pub fn create_game_matcher(mut stream: TcpStream) -> std::io::Result<()> {
println!("Creating a new game! Waiting for the code.");
let game_code: String;
let len: usize;
loop {
match loby_matcher(&mut stream) {
Ok((game_code_, len_)) => {
game_code = game_code_;
len = len_;
break;
}
Err(e) if e.to_string() == "wrong game code" => {
stream.write("Wrong coden".as_bytes())?;
}
Err(e) => return Err(e),
};
}
println!("Received : {} size {}", game_code, len);
// println!("Closing connection now I guess?");
Ok(())
}

最新更新