[我正在尝试使用Rust程序(TCP服务器)中的线程来处理TcpStream
。我想使用HashMap
跟踪Arc<Mutex<HashMap>>
中当前客户端的连接。
[线程完成后,为了从HashMap中删除连接,我考虑过使用uuid
,该参数传递给用于处理流的函数。这样,它可以在mpsc通道内发送到主线程,然后从HashMap
中删除连接。
来自主线程的代码:
let clients_streams = Arc::new(Mutex::new(HashMap::new()));
// Server thread. Create channel
let (server_sender, server_receiver) = mpsc::channel();
loop {
for stream in server_socket.incoming() {
let clients_streams = Arc::clone(&clients_streams);
let server_sender = server_sender.clone();
let mut cs = clients_streams.lock().unwrap();
match stream {
Ok(stream) => {
let mut cs = clients_streams.lock().unwrap();
let uuid = Uuid::new_v4().to_string();
cs.insert(uuid.clone(), stream.try_clone());
thread::spawn(move || {
handle_client(stream, server_sender.clone(), uuid.clone());
})
}
Err(err) => thread::spawn(move || {
println!("Connection failed : {}", err);
}),
};
}
handle_client
功能:
fn handle_client<'a>(stream: TcpStream, sender: mpsc::Sender<&'a [u8]>, uuid: String) {
let mut reader = BufReader::new(&stream);
let mut writer = BufWriter::new(&stream);
writer.write(b"Hello\n").unwrap();
writer.flush().unwrap();
// Read from client
loop {
let mut resp = Vec::new();
let read_bytes = reader.read_until(b'\n', &mut resp);
match read_bytes {
Ok(read_bytes) => {
if read_bytes == 0 {
let msg = format!("end of {}", uuid);
println!("connection closed by remote");
sender.send(msg.as_bytes()).unwrap();
break;
};
}
Err(err) => match err.kind() {
io::ErrorKind::Interrupted => continue,
_ => break,
},
}
}
}
此代码未编译,显示了此错误,但我不知道如何解决。变量msg
的生存时间不够长,这是因为变量uuid
内部存在,但是为什么呢?我必须添加生存期,因为我要在通道内发送uuid
。
fn handle_client<'a>(stream: TcpStream, sender: mpsc::Sender<&'a [u8]>, uuid: String) {
-- lifetime `'a` defined here
sender.send(msg.as_bytes()).unwrap();
------------^^^------------
| |
| borrowed value does not live long enough
argument requires that `msg` is borrowed for `'a`
break;
};
- `msg` dropped here while still borrowed
Uuid不会影响msg,因为format宏会创建一个干净的新String。您正在尝试发送&[u8](这是as_bytes()返回的内容)。您需要找到一种删除此引用的方法。 (也许像How to convert from &[u8] to Vec<u8>?这样的东西。)您也可以与Rc共享引用。
PS:这不是评论,而是答案,但我无法发布答案