import socket import threading import json import os DB_FILE = "chat_db.json" ONLINE_USERS = {} # {username: conn} # 初始化数据库 if not os.path.exists(DB_FILE): with open(DB_FILE, "w") as f: json.dump({"users": {}, "messages": []}, f) def load_db(): with open(DB_FILE, "r") as f: return json.load(f) def save_db(data): with open(DB_FILE, "w") as f: json.dump(data, f, indent=2, ensure_ascii=False) def handle_client(conn, addr): username = None try: while True: data = conn.recv(1024).decode("utf-8") if not data: break req = json.loads(data) action = req.get("action") if action == "register": db = load_db() users = db["users"] if req["username"] in users: conn.send(json.dumps({"status": "fail", "msg": "用户已存在"}).encode("utf-8")) else: users[req["username"]] = req["password"] save_db(db) conn.send(json.dumps({"status": "ok", "msg": "注册成功"}).encode("utf-8")) elif action == "login": db = load_db() users = db["users"] if users.get(req["username"]) == req["password"]: username = req["username"] ONLINE_USERS[username] = conn conn.send(json.dumps({"status": "ok", "msg": "登录成功"}).encode("utf-8")) broadcast_users() else: conn.send(json.dumps({"status": "fail", "msg": "用户名或密码错误"}).encode("utf-8")) elif action == "list_users": users = list(ONLINE_USERS.keys()) if username in users: users.remove(username) # 移除自己 conn.send(json.dumps({"status": "ok", "users": users}).encode("utf-8")) elif action == "send": to_user = req["to"] msg = req["msg"] db = load_db() db["messages"].append({"from": username, "to": to_user, "msg": msg}) save_db(db) if to_user in ONLINE_USERS: ONLINE_USERS[to_user].send( json.dumps({"status": "msg", "from": username, "msg": msg}).encode("utf-8") ) else: conn.send(json.dumps({"status": "fail", "msg": "对方不在线"}).encode("utf-8")) except Exception as e: print(f"错误: {e}") finally: if username and username in ONLINE_USERS: del ONLINE_USERS[username] broadcast_users() conn.close() def broadcast_users(): users = list(ONLINE_USERS.keys()) for user, conn in ONLINE_USERS.items(): ulist = [u for u in users if u != user] try: conn.send(json.dumps({"status": "system", "users": ulist}).encode("utf-8")) except: pass def main(): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(("0.0.0.0", 8888)) server.listen(5) print("服务器已启动,监听 8888 端口...") while True: conn, addr = server.accept() threading.Thread(target=handle_client, args=(conn, addr), daemon=True).start() if __name__ == "__main__": main()