You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:33:26