基于Python Socket的公服私聊实现及带密码多聊天室开发需求
Socket聊天室:私聊与带密码多房间实现
一、修复并实现私聊功能(类似/w命令)
你的现有代码存在Python语法适配、用户映射逻辑缺失、命令解析不完善等问题,以下是修正后的完整实现:
1. 基础结构与依赖导入
import socket import re import threading # 存储在线用户:{用户名: 连接对象} client_list = {} # 存储连接对应的用户名:{连接对象: 用户名} conn_to_username = {}
2. 客户端处理函数(核心逻辑)
def client_handler(connection): # 引导用户设置用户名 connection.send(str.encode('请输入你的用户名:')) username = connection.recv(2048).decode('utf-8').strip() # 注册用户映射关系 client_list[username] = connection conn_to_username[connection] = username connection.send(str.encode( f'你已连接到服务器,当前在线用户:{", ".join(client_list.keys())}\n' '输入/w <用户名> <消息> 发送私聊;输入BYE退出;直接输入内容发送公共消息' )) while True: try: data = connection.recv(2048) if not data: break message = data.decode('utf-8').strip() # 处理退出命令 if message == 'BYE': break # 处理私聊命令:匹配/w开头的格式 private_match = re.match(r'^/w (\S+) (.+)$', message) if private_match: target_username = private_match.group(1) private_msg = private_match.group(2) # 校验目标用户是否在线 if target_username in client_list: target_conn = client_list[target_username] # 给目标用户发送私聊内容 target_conn.send(str.encode(f'[私聊] {username}: {private_msg}')) # 给发送者反馈发送成功 connection.send(str.encode(f'[私聊已发送] 给 {target_username}: {private_msg}')) else: connection.send(str.encode(f'错误:用户 {target_username} 不在线,请重试')) # 私聊处理完成,跳过公共消息逻辑 continue # 处理公共消息:广播给所有在线用户(排除自己) public_msg = f'[公共] {username}: {message}' for conn in client_list.values(): if conn != connection: conn.send(str.encode(public_msg)) else: connection.send(str.encode(f'[你] {message}')) except Exception as e: print(f'消息处理出错:{e}') break # 用户退出后清理映射 del client_list[conn_to_username[connection]] del conn_to_username[connection] connection.close() # 广播用户退出通知 exit_msg = f'[系统] {username} 已退出聊天室' for conn in client_list.values(): conn.send(str.encode(exit_msg))
3. 服务器启动逻辑
def start_server(host='0.0.0.0', port=12345): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) server_socket.listen(5) print(f'服务器启动,监听 {host}:{port}') while True: conn, addr = server_socket.accept() print(f'新连接:{addr}') threading.Thread(target=client_handler, args=(conn,)).start() if __name__ == '__main__': start_server()
二、实现带密码的多房间系统(类似/party)
基于上述基础,新增房间管理逻辑,实现专属密码房间功能:
1. 新增房间存储结构
# 存储房间信息:{房间名: {"password": 密码, "members": [连接对象列表], "member_names": [用户名列表]}} rooms = {}
2. 扩展客户端处理函数(加入房间命令)
在client_handler函数开头,注册用户名后新增当前房间标记:
current_room = None # 记录用户当前所在房间
然后在消息处理循环中加入房间命令解析:
# 处理房间创建命令 create_match = re.match(r'^/create (\S+) (\S+)$', message) if create_match: room_name = create_match.group(1) room_pwd = create_match.group(2) if room_name in rooms: connection.send(str.encode(f'错误:房间 {room_name} 已存在')) else: # 创建房间并自动加入当前用户 rooms[room_name] = { "password": room_pwd, "members": [connection], "member_names": [username] } current_room = room_name connection.send(str.encode( f'已创建并加入房间 {room_name},房间密码:{room_pwd}\n' '输入房间内消息仅成员可见;输入/leave退出房间;/w命令仍可跨房间私聊' )) continue # 处理房间加入命令 join_match = re.match(r'^/join (\S+) (\S+)$', message) if join_match: room_name = join_match.group(1) input_pwd = join_match.group(2) if room_name not in rooms: connection.send(str.encode(f'错误:房间 {room_name} 不存在')) elif input_pwd != rooms[room_name]["password"]: connection.send(str.encode('错误:密码不正确')) else: # 添加用户到房间 rooms[room_name]["members"].append(connection) rooms[room_name]["member_names"].append(username) current_room = room_name # 通知房间内其他成员 join_notify = f'[系统] {username} 加入了房间 {room_name}' for conn in rooms[room_name]["members"]: conn.send(str.encode(join_notify)) continue # 处理房间退出命令 if message == '/leave': if not current_room: connection.send(str.encode('错误:你当前不在任何房间')) else: # 移除用户并通知房间成员 rooms[current_room]["members"].remove(connection) rooms[current_room]["member_names"].remove(username) leave_notify = f'[系统] {username} 离开了房间 {current_room}' for conn in rooms[current_room]["members"]: conn.send(str.encode(leave_notify)) # 房间为空则删除 if not rooms[current_room]["members"]: del rooms[current_room] current_room = None connection.send(str.encode('已退出房间,回到公共频道')) continue
3. 调整消息广播范围
将原公共消息广播逻辑替换为:
# 处理普通消息(非命令) if current_room: # 房间内消息仅广播给房间成员 room_msg = f'[{current_room}] {username}: {message}' for conn in rooms[current_room]["members"]: if conn != connection: conn.send(str.encode(room_msg)) else: connection.send(str.encode(f'[你在{current_room}] {message}')) else: # 公共频道消息仅发送给未加入房间的用户 public_msg = f'[公共] {username}: {message}' for conn in client_list.values(): # 判断对方是否在房间内 in_room = False for room in rooms.values(): if conn in room["members"]: in_room = True break if not in_room and conn != connection: conn.send(str.encode(public_msg)) elif conn == connection: connection.send(str.encode(f'[你] {message}'))
核心功能说明
- 私聊命令
/w <用户名> <消息>:精准发送给目标用户,仅双方可见 - 房间命令:
/create <房间名> <密码>:创建带密码的专属房间并自动加入/join <房间名> <密码>:验证密码后加入指定房间/leave:退出当前房间回到公共频道
- 房间内消息仅成员可见,公共消息仅未加入房间的用户可见,私聊不受房间限制
内容的提问来源于stack exchange,提问作者2D Vortex
相关产品推荐
相关产品推荐

