use std::collections::HashMap;
use std::net::{TcpListener, TcpStream};
use std::io::{BufRead, BufReader, Write};
use std::sync::{Arc, Mutex};
use std::thread;
use chrono::Local;
#[allow(dead_code)]
type ClientMap = Arc<Mutex<HashMap<String, TcpStream>>>;
#[allow(dead_code)]
pub fn server_main() {
let server_addr = "0.0.0.0:52525";
println!("🔧 네트워크 디버깅 정보:");
println!(" - 서버 바인딩 주소: {}", server_addr);
match std::process::Command::new("hostname").arg("-I").output() {
Ok(output) => {
let ips = String::from_utf8_lossy(&output.stdout);
println!(" - 사용 가능한 IP 주소들: {}", ips.trim());
}
Err(_) => println!(" - IP 주소 확인 실패"),
}
let listener = TcpListener::bind(server_addr).expect("서버 바인딩 실패");
println!("🚀 채팅 서버가 {}에서 시작되었습니다", server_addr);
println!("📡 클라이언트 연결을 기다리는 중...\n");
let clients: ClientMap = Arc::new(Mutex::new(HashMap::new()));
for (client_id, stream) in listener.incoming().enumerate() {
match stream {
Ok(stream) => {
let client_addr = stream.peer_addr().unwrap();
let client_name = format!("Client_{}", client_id);
println!("✅ 새 클라이언트 연결: {} ({})", client_name, client_addr);
let clients_clone = Arc::clone(&clients);
let stream_clone = stream.try_clone().unwrap();
clients_clone.lock().unwrap().insert(client_name.clone(), stream_clone);
thread::spawn(move || {
handle_client(stream, client_name, clients_clone);
});
}
Err(e) => {
eprintln!("❌ 클라이언트 연결 오류: {}", e);
}
}
}
}
fn handle_client(stream: TcpStream, client_name: String, clients: ClientMap) {
let mut reader = BufReader::new(stream.try_clone().unwrap());
let mut buffer = String::new();
loop {
buffer.clear();
match reader.read_line(&mut buffer) {
Ok(0) => {
println!("🔌 {} 연결 종료", client_name);
clients.lock().unwrap().remove(&client_name);
break;
}
Ok(_) => {
let message = buffer.trim();
let timestamp = Local::now().format("%H:%M:%S");
println!("💬 [{}] {}: {}", timestamp, client_name, message);
broadcast_message(&clients, &format!("[{}] {}: {}", timestamp, client_name, message));
}
Err(e) => {
eprintln!("❌ {} 메시지 읽기 오류: {}", client_name, e);
clients.lock().unwrap().remove(&client_name);
break;
}
}
}
}
fn broadcast_message(clients: &ClientMap, message: &str) {
let mut clients_lock = clients.lock().unwrap();
let mut disconnected_clients = Vec::new();
for (client_name, stream) in clients_lock.iter_mut() {
if let Err(_) = writeln!(stream, "{}", message) {
disconnected_clients.push(client_name.clone());
}
}
for client_name in disconnected_clients {
clients_lock.remove(&client_name);
}
}