Hello. I'm new to Rust.
I'm making a TCP server with Rust.
I coukd
mod errors;
mod result;
#[cfg(test)]
mod tests;
use std::io::{Error, Read, Write};
use std::net::{TcpListener, TcpStream};
use std::thread;
pub use self::errors::ServerSessionError;
pub use self::result::ServerSessionResult;
pub struct Server {
addr: Option<String>,
listener: TcpListener,
}
impl Server {
pub fn new() -> Result<(Server, Vec<ServerSessionResult>), ServerSessionError> {
let server = Server {
addr: Some("somewhere".to_string()),
listener: TcpListener::bind("127.0.0.1:1935").unwrap(),
};
let mut results = Vec::with_capacity(4);
Ok((server, results))
}
pub fn listen_and_serve(&self) {
// Build a server
println!("Listening...");
for streams in self.listener.incoming() {
match streams {
Err(e) => { eprintln!("error: {}", e) },
Ok(stream) => {
thread::spawn(move || {
handler(stream).unwrap_or_else(|error| eprintln!("{:?}", error));
});
}
}
}
}
pub fn terminate(&self) {
// Terminate a server
drop(self.listener);
}
}
fn handler(mut stream: TcpStream) -> Result<(), Error> {
println!("Connection from {}", stream.peer_addr()?);
let mut buffer = [0; 1024];
loop {
let nbytes = stream.read(&mut buffer)?;
if nbytes == 0 {
return Ok(());
}
stream.write(&buffer[..nbytes])?;
stream.flush()?;
}
}
Running it, an error occurs
Compiling inferno-rtmp-engine v0.1.0 (/Users/kunosouichirou/Documents/GitHub/Inferno/inferno/inferno-rtmp-engine)
warning: trait objects without an explicit `dyn` are deprecated
--> inferno-rtmp-engine/src/servers/errors.rs:24:32
|
24 | fn cause(&self) -> Option<&Fail> {
| ^^^^ help: use `dyn`: `dyn Fail`
|
= note: `#[warn(bare_trait_objects)]` on by default
warning: variable does not need to be mutable
--> inferno-rtmp-engine/src/servers/mod.rs:26:13
|
26 | let mut results = Vec::with_capacity(4);
| ----^^^^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
error[E0507]: cannot move out of `self.listener` which is behind a shared reference
--> inferno-rtmp-engine/src/servers/mod.rs:48:14
|
48 | drop(self.listener);
| ^^^^^^^^^^^^^ move occurs because `self.listener` has type `std::net::TcpListener`, which does not implement the `Copy` trait
error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`.
error: could not compile `inferno-rtmp-engine`.
To learn more, run the command again with --verbose.
Without my terminate() function, it works properly.
But I want to stop the TCP server with a function for unit testing.
How can I close the server?