我想编写一个处理数据的串行/ TCP网关。我有两个HashMap
(trans_socket_map
和token_socket_map
)。我不知道如何解决它。
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