use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let listener = TcpListener::bind("127.0.0.1:8080").expect("Failed to bind");
let clients = Arc::new(Mutex::new(Vec::new()));
for stream in listener.incoming() {
let stream = stream.expect("Failed to accept");
let clients_clone = clients.clone();
thread::spawn(move || {
handle_client(stream, clients_clone);
});
}
}
fn handle_client(mut stream: TcpStream, clients: Arc<Mutex<Vec<TcpStream>>>) {
let mut buffer = [0; 1024];
let read_result = stream.read(&mut buffer);
let read_bytes = match read_result {
Ok(n) => n,
Err(e) => {
println!("Failed to read from client: {}", e);
return;
}
};
let message = String::from_utf8_lossy(&buffer[..read_bytes]);
let mut clients_guard = clients.lock().expect("Failed to lock clients");
for client in clients_guard.iter_mut() {
if let Err(e) = client.write_all(message.as_bytes()) {
println!("Failed to write to client: {}", e);
}
}
clients_guard.push(stream);
}
- 创建监听套接字:使用
TcpListener::bind
绑定到指定地址和端口。
- 管理客户端连接:
- 使用
Arc<Mutex<Vec<TcpStream>>>
来管理所有已连接的客户端。Arc
用于在多个线程间共享数据,Mutex
用于确保线程安全的访问。
- 处理每个客户端连接:
- 在
listener.incoming()
的循环中,为每个新连接的客户端创建一个新线程。
handle_client
函数负责从客户端读取数据,并将数据广播给所有已连接的客户端。
- 在读取和广播数据时,使用
Mutex
来保护对clients
向量的访问,避免资源竞争。