借阅和参考

时间:2019-10-15 21:41:53

标签: reference rust hashmap tcpserver borrowing

我想编写一个处理数据的串行/ TCP网关。我有两个HashMaptrans_socket_maptoken_socket_map)。我不知道如何解决它。

Playground

use mio::{
    net::{TcpListener, TcpStream},
    Events, Poll, PollOpt, Ready, Token,
}; // 0.6.19
use std::{
    collections::HashMap,
    io::{self, Read},
};

#[derive(PartialOrd, Eq, Hash)]
struct Transaction {
    transaction_id: Vec<u8>,
    proto_id: Vec<u8>,
    len_field: Vec<u8>,
    unit_id: u8,
    func_nr: u8,
    count_bytes: u8,
}

impl PartialEq for Transaction {
    fn eq(&self, other: &Self) -> bool {
        self.unit_id == other.unit_id
            && self.func_nr == other.func_nr
            && self.count_bytes == other.count_bytes
    }
}

fn main() {
    let mut trans_socket_map: HashMap<Transaction, &TcpStream> = HashMap::new();
    let mut token_socket_map: HashMap<Token, TcpStream> = HashMap::new();

    let address = "0.0.0.0:1502";
    let listener = TcpListener::bind(&address.parse().unwrap()).unwrap();

    let poll = Poll::new().unwrap();
    poll.register(&listener, Token(0), Ready::readable(), PollOpt::edge())
        .unwrap();

    let mut events = Events::with_capacity(1024);
    let mut counter: usize = 0;

    loop {
        poll.poll(&mut events, None).unwrap();
        for event in &events {
            match event.token() {
                Token(0) => {
                    loop {
                        match listener.accept() {
                            Ok((socket, _)) => {
                                counter += 1;
                                let token = Token(counter);
                                // Register for readable events
                                poll.register(
                                    &socket,
                                    token,
                                    Ready::readable() | Ready::writable(),
                                    PollOpt::urgent(),
                                )
                                .unwrap();
                                token_socket_map.insert(token, socket);
                            }
                            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock =>
                            // No more connections ready to be accepted
                            {
                                break
                            }
                            Err(e) => panic!("Unexpected error: {}", e),
                        }
                    }
                }
                token if event.readiness().is_readable() => {
                    // Socket associated with token is ready for reading data from it
                    let mut buffer = [0 as u8; 1024];
                    let mut sock = token_socket_map.get(&token).unwrap();
                    loop {
                        let read = sock.read(&mut buffer);
                        match read {
                            Ok(0) => {
                                //sockets.remove(&token);
                                break;
                            }
                            Ok(size) => {
                                let t = Transaction {
                                    transaction_id: buffer[0..2].to_vec(),
                                    proto_id: buffer[2..4].to_vec(),
                                    len_field: buffer[4..6].to_vec(),
                                    unit_id: buffer[6],
                                    func_nr: buffer[7],
                                    count_bytes: buffer[11] * 2,
                                };
                                trans_socket_map.insert(t, &sock);
                                break;
                            }
                            Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
                            Err(_) => break,
                        }
                    }
                }
                _ => (), // Ignore all other tokens
            }
        }
    }
}

问题在于借用变量:

error[E0502]: cannot borrow `token_socket_map` as mutable because it is also borrowed as immutable
  --> src/main.rs:60:33
   |
60 |                                 token_socket_map.insert(token, socket);
   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
74 |                     let mut sock = token_socket_map.get(&token).unwrap();
   |                                    ---------------- immutable borrow occurs here
...
91 |                                 trans_socket_map.insert(t, &sock);
   |                                 ---------------- immutable borrow later used here

0 个答案:

没有答案