新手问个问题……

2022-03-23 18:18:06 +08:00
 fgwmlhdkkkw

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 中的记录。

1314 次点击
所在节点    Rust
3 条回复
fgwmlhdkkkw
2022-03-23 18:23:29 +08:00
😭😭😭😭😭
fgwmlhdkkkw
2022-03-23 20:39:19 +08:00
咋没人呀,,再顶最后一次🤕
fgwmlhdkkkw
2022-03-25 12:11:12 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/842435

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX