【问题标题】:rust - Send data from function argument (from a thread) into mpsc channelrust - 将数据从函数参数(从线程)发送到 mpsc 通道
【发布时间】:2019-10-27 15:07:14
【问题描述】:

我正在尝试使用 Rust 程序(tcp 服务器)中的线程来处理 TcpStream。我想使用Arc<Mutex<HashMap>> 跟踪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

【问题讨论】:

    标签: rust


    【解决方案1】:

    Uuid 不会影响 msg,因为格式宏会创建一个干净的新字符串。您正在尝试发送 &[u8] (这是 as_bytes() 返回的内容)。您需要找到一种方法来删除此引用。 (也许这类似于How to convert from &[u8] to Vec<u8>?)您也可以与 Rc 共享参考。

    PS:这更像是评论而不是答案,但我无法发布答案

    【讨论】:

    • 我现在在频道中发送Vec&lt;u8&gt; 而不是&amp;[u8],现在它可以工作了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 2020-02-25
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 2021-05-01
    相关资源
    最近更新 更多