在mio文档的旧版本中,我找到了mio:: channel,它似乎是用来创建一个可以向Poll注册的实现EventedFd的通道。我还在reddit上看到,这是为了支持其他东西而改变的,但我不知道注册频道的新方式是什么。
到目前为止,使用mio等待频道(std::sync::mpsc或其他东西)的方式是什么?我在google上找到的只是mio docs的旧版本的链接。谢谢!
当我遇到同样的问题时,我希望可以,我提供了一些代码来使问题更容易理解:
use std::io;
use std::net::*; //{TcpListener,TcpStream,IpAddr,Ipv4Addr,SocketAddr};
use std::thread::*;
use std::sync::mpsc::*; //{Receiver,SyncSender,Sender,channel,sync_channel};
fn poll_quit( rx : &Receiver::<u8> ) -> bool {
match rx.try_recv() {
Ok(_) => true,
Err(TryRecvError::Empty) => false,
Err(TryRecvError::Disconnected) => true
}
}
fn guard_external_tcp_port( rx : Receiver::<u8>) -> () {
let listener = TcpListener::bind("127.0.0.1:8384").expect("tcp guard - bind failed!");
listener.set_nonblocking(true).expect("cannot set tcp listener to nonblocking!");
while false == poll_quit(&rx) {
match listener.accept() {
Ok((_s,pa)) => {
println!("tcp client connected: {} - closing it down."
, pa);
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
//wait_for_fd();
continue;
}
Err(e) => panic!("encountered IO error: {}", e),
}
}
}
fn start_tcpguard() -> (JoinHandle<()>,SyncSender::<u8>) {
let (tx,rx) = sync_channel::<u8>(0);
let thrd = spawn(move || {
guard_external_tcp_port(rx);
});
(thrd,tx)
}到目前为止,我尝试过不使用mio,但问题很明显:您希望阻塞,直到关闭通道消息到达或监听程序套接字被通知为止。有足够的动力切换到mio。除非mio不能等待Receiver。
发布于 2019-05-02 05:33:16
现在还有另一个mio crate,它具有与通道相关的功能:
因此,您要做的就是将该板条箱添加到您的cargo.toml [dependencies]中。
然后,在您的main.rs中添加extern crate mio_extras,您就应该可以使用它了。
因此,在我添加到问题中的代码片段中,它最终看起来是这样的:
extern crate mio;
extern crate mio_extras;
use std::io;
use mio::*;
use mio::net::*;
use mio_extras::channel::*;
use std::thread::*;
fn guard_external_tcp_port( rx : mio_extras::channel::Receiver::<u8>) -> () {
let poll = Poll::new().expect("could not create a new Poll instance.");
const QUIT : Token = Token(0);
const CONNECT : Token = Token(1);
let mut events = Events::with_capacity(5);
poll.register(&rx,QUIT,Ready::readable(),PollOpt::level() ).expect("could not register channel Receiver.");
let addr : std::net::SocketAddr = "127.0.0.1:8384".parse().unwrap();
let listener = TcpListener::bind(&addr).expect("tcp guard - bind failed!");
poll.register(&listener,CONNECT,Ready::all(),PollOpt::edge()).expect("could not register our listening socket.");
let mut running : bool = true;
//listener.set_nonblocking(true).expect("cannot set tcp listener to nonblocking!");
while running {
let _nevents = poll.poll(&mut events,None).unwrap();
println!("poll returned!");
for event in &events {
match event.token() {
QUIT => running = false,
CONNECT => {
match listener.accept() {
Ok((_s,pa)) => {
println!("tcp client connected: {} - closing it down."
, pa);
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
//wait_for_fd();
continue;
}
Err(e) => panic!("encountered IO error: {}", e),
}
},
Token(_) => continue
}
}
}
}
fn start_tcpguard() -> (JoinHandle<()>,Sender::<u8>) {
let (tx,rx) = mio_extras::channel::channel::<u8>();
let thrd = spawn(move || {
guard_external_tcp_port(rx);
});
(thrd,tx)
}我也尝试了sync_channel(0)版本,但它无法按预期工作。不过,上面代码中的版本只适用于接收关闭事件的轮询。
https://stackoverflow.com/questions/55862360
复制相似问题