V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fgwmlhdkkkw
V2EX  ›  Rust

新手问个问题……

  •  
  •   fgwmlhdkkkw · 2022-03-23 18:18:06 +08:00 · 1421 次点击
    这是一个创建于 975 天前的主题,其中的信息可能已经有所发展或是发生改变。

    conn.rs

    use std::hash::{Hash, Hasher};
    use std::net;
    use std::sync::{Arc, Mutex};
    
    use crate::simplehttp::options;
    use crate::simplehttp::server;
    
    pub struct Conn {
    	conn: net::TcpStream,
    }
    
    impl Conn {
    	pub fn new(conn: net::TcpStream) -> Self {
    		return Conn { conn };
    	}
    
    	pub fn handle(mut conn: Arc<Conn>) {
    		println!("{:?}", conn.conn.peer_addr());
    	}
    }
    
    impl PartialEq<Self> for Conn {
    	fn eq(&self, other: &Self) -> bool {
    		return self as (*const Self) as u64 == other as (*const Self) as u64;
    	}
    }
    
    impl Eq for Conn {}
    
    impl Hash for Conn {
    	fn hash<H: Hasher>(&self, state: &mut H) {
    		state.write_u64(self as (*const Self) as u64);
    	}
    
    	fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) where Self: Sized {
    		for datum in data {
    			state.write_u64(datum as (*const Self) as u64);
    		}
    	}
    }
    

    server.rs

    use std::{net, thread};
    use std::borrow::BorrowMut;
    use std::collections::HashSet;
    use std::net::TcpListener;
    use std::ptr::NonNull;
    use std::sync::{Arc, Mutex};
    
    use crate::simplehttp::conn;
    use crate::simplehttp::options;
    
    pub struct Server {
    	host: String,
    	port: u16,
    
    	running: Mutex<bool>,
    	listener: Option<Box<TcpListener>>,
    	alive: Mutex<HashSet<Arc<conn::Conn>>>,
    }
    
    
    impl Server {
    	pub fn new(host: String, port: u16) -> Self {
    		return Server {
    			host,
    			port,
    			running: Mutex::new(false),
    			listener: None,
    			alive: Mutex::new(HashSet::new()),
    		};
    	}
    
    	pub fn run(&mut self) {
    		let mut running_guard = self.running.lock().unwrap();
    		if *running_guard {
    			panic!("server, {}:{} is already running", self.host, self.port);
    		}
    		*running_guard = true;
    		std::mem::drop(running_guard);
    
    		self.listener = Some(Box::new(TcpListener::bind(format!("{}:{}", self.host, self.port)).unwrap()));
    		println!("simplehttpserver: running @ {}:{}", self.host, self.port);
    
    		for stream in self.listener.as_ref().unwrap().incoming() {
    			match stream {
    				Ok(stream) => {
    					let mut conn = Arc::new(conn::Conn::new(stream));
    
    					let mut alive_guard = self.alive.lock().unwrap();
    					// (*alive_guard).insert(conn.clone());
    					std::mem::drop(alive_guard);
    
    					let mut new_conn = conn.clone();
    					thread::spawn(move || {
    						conn::Conn::handle(new_conn);
    					});
    				}
    				Err(e) => {
    					println!("connection error: {:?}", e);
    				}
    			}
    		}
    	}
    }
    

    怎么才能做到 Conn 持有 Server 的 Arc 呀? 我想要 Conn::handle 结束之后,删除在 Server.alive 中的记录。

    3 条回复
    fgwmlhdkkkw
        1
    fgwmlhdkkkw  
    OP
       2022-03-23 18:23:29 +08:00
    😭😭😭😭😭
    fgwmlhdkkkw
        2
    fgwmlhdkkkw  
    OP
       2022-03-23 20:39:19 +08:00 via Android
    咋没人呀,,再顶最后一次🤕
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2876 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 06:52 · PVG 14:52 · LAX 22:52 · JFK 01:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.