在第一次从流中读取时,函数将流读取到 var“name”并打印是没有问题的,但进入循环后,不会读取下一个收入流。 只需输入 tokio::select 当流关闭时即可打印连接已关闭。
async fn main(){
let listener = TcpListener::bind("localhost:3001").await.unwrap();
let (tx, _rx) = broadcast::channel(10);
loop{
let (mut stream, socket_addr) = listener.accept().await.unwrap();
let tx = tx.clone();
let mut rx = tx.subscribe();
tokio::spawn(async move {
let mut name = [0;16];
stream.read(&mut name).await.unwrap();
let name = String::from_utf8_lossy(&name).to_string();
println!("{name} Connected.");
let (reader, mut writer) = stream.split();
let mut reader = BufReader::new(reader);
let mut line = String::new();
loop {
tokio::select! {
result = reader.read_line(&mut line)=> {
if let Err(_) = result{
println!("Connection lost with {name}");
break;
}
if line.len() == 0{
break;
}
let mut line = format!("{}: {}", &name, &line);
println!("{line}");
tx.send((line.clone(), socket_addr)).unwrap();
line.clear();
}
result = rx.recv() => {
let (msg, other_addr) = result.unwrap();
let msg = msg.trim_end_matches('\n');
if other_addr == socket_addr {
}
if other_addr != socket_addr {
let msg = msg.as_bytes();
writer.write_all(msg).await.unwrap();
}
}
}
}
});
}
}
不知道为什么,但是如果你把read_line函数改成read,就可以了。