下面的代码应该接受 tcp 连接,从中读取,并在挂断时关闭它们。
extern crate mio;
use mio::{EventLoop,Token,ReadHint};
use mio::tcp::{TcpListener, TcpStream};
use std::io::Read;
const L_CLIENT: Token = Token(0);
const C_CLIENT: Token = Token(1);
fn sa(port:u16) -> std::net::SocketAddr {
let ipa : std::net::Ipv4Addr = std::net::Ipv4Addr::new(127,0,0,1);
std::net::SocketAddr::V4(std::net::SocketAddrV4::new(ipa,port))
}
fn main(){
let mut event_loop = EventLoop::new().unwrap();
let lclient = TcpListener::bind(&sa(4000)).unwrap();
event_loop.register(&lclient, L_CLIENT).unwrap();
println!("running loop...");
event_loop.run(&mut MyHandler{lclient:lclient,cclient:None}).unwrap();
println!("done.");
}
struct MyHandler{
lclient:TcpListener,
cclient:Option<TcpStream>,
}
impl mio::Handler for MyHandler {
type Timeout = ();
type Message = ();
fn readable(&mut self, event_loop: &mut EventLoop<Self>, token: Token, hint: ReadHint){
match token {
L_CLIENT => {
let s=self.lclient.accept().unwrap().expect("no client??");
match self.cclient{
None => {event_loop.register(&s,C_CLIENT);self.cclient=Some(s);}
Some(_) =>{println!("ignore second client");} // s should be closed as it goes out of scope
}
},
C_CLIENT => {
let mut client=self.cclient.expect("connection is gone"); // what's the problem here?
if hint.is_hup() {
event_loop.deregister(&client);
self.cclient=None; // how to close connection?
} else {
let mut buf: [u8; 500] = [0; 500];
let l=client.read(&mut buf).unwrap();
println!("read {} bytes.",l);
}
},
_ =>{println!("other Token");}
}
}
}
这几乎可以工作。在 C_CLIENT 情况下,我想处理客户端挂断。在那种情况下,我想我需要将连接的所有权从我的处理程序转移到方法,以便让它超出范围以关闭它。
不幸的是,rust 不允许我移动连接:
error: cannot move out of borrowed content
据我了解,问题在于&self
该方法是借用的readable
,因此无法访问其字段。
如何访问连接?(避免上述错误。)
如何关闭该连接?(即转让所有权。)