找回密码
 中文实名注册
查看: 74|回复: 0

聊天室

[复制链接]

3

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2025-2-16 17:28:04 | 显示全部楼层 |阅读模式
本帖最后由 李承键 于 2025-2-16 17:30 编辑

[C++] 纯文本查看 复制代码
import socket
import threading

# 服务器配置
HOST = '127.0.0.1'
PORT = 58588

# 创建 TCP 套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen()

# 存储所有连接的客户端
clients = []
nicknames = []

# 广播消息给所有客户端
def broadcast(message):
    for client in clients:
        client.send(message)

# 发送在线用户列表给所有客户端
def send_online_users():
    users_str = ','.join(nicknames)
    message = f'USERS{users_str}'.encode('utf-8')
    broadcast(message)

# 处理客户端连接
def handle(client):
    while True:
        try:
            # 接收客户端消息
            message = client.recv(1024)
            if not message:
                break
            broadcast(message)
        except:
            # 处理客户端断开连接
            index = clients.index(client)
            clients.remove(client)
            client.close()
            nickname = nicknames[index]
            nicknames.remove(nickname)
            broadcast(f'{nickname} 离开了聊天室!'.encode('utf-8'))
            send_online_users()
            break

# 接收新的客户端连接
def receive():
    while True:
        client, address = server_socket.accept()
        print(f'连接地址: {str(address)}')

        # 发送昵称请求
        client.send('NICK'.encode('utf-8'))
        nickname = client.recv(1024).decode('utf-8')
        nicknames.append(nickname)
        clients.append(client)

        print(f'用户 {nickname} 已加入!')
        broadcast(f'{nickname} 加入了聊天室!'.encode('utf-8'))
        client.send('已连接到服务器!'.encode('utf-8'))
        send_online_users()

        # 为每个客户端创建一个线程来处理消息
        thread = threading.Thread(target=handle, args=(client,))
        thread.start()

print("服务器正在监听...")
receive()

import socket
import threading
import tkinter as tk
from tkinter import simpledialog, messagebox
from tkinter import scrolledtext
import winsound  # 用于播放提示音,仅适用于Windows系统

# 全局变量
client = None
nickname = None
online_users = []

# 接收服务器消息
def receive():
    global online_users
    while True:
        try:
            # 接收服务器消息
            message = client.recv(1024).decode('utf-8')
            if message.startswith('NICK'):
                client.send(nickname.encode('utf-8'))
            elif message.startswith('USERS'):
                # 更新在线用户列表
                users_str = message[6:]
                online_users = users_str.split(',')
                update_user_list()
            else:
                chat_box.insert(tk.END, message + '\n')
                # 播放提示音
                winsound.Beep(500, 200)
        except:
            # 发生错误,关闭连接
            messagebox.showerror("错误", "与服务器的连接已断开!")
            client.close()
            break

# 发送消息到服务器
def send_message(event=None):
    message = input_box.get()
    input_box.delete(0, tk.END)
    if message:
        client.send(f'{nickname}: {message}'.encode('utf-8'))

# 连接到服务器
def connect():
    global client, nickname
    server_ip = ip_entry.get()
    if not server_ip:
        messagebox.showerror("错误", "请输入服务器IP地址!")
        return

    try:
        nickname = simpledialog.askstring("昵称", "请输入你的昵称:")
        if nickname:
            client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            client.connect((server_ip, 58588))

            receive_thread = threading.Thread(target=receive)
            receive_thread.start()

            connect_button.config(state=tk.DISABLED)
            ip_entry.config(state=tk.DISABLED)
    except:
        messagebox.showerror("错误", "无法连接到服务器!")

# 更新在线用户列表
def update_user_list():
    user_listbox.delete(0, tk.END)
    for user in online_users:
        user_listbox.insert(tk.END, user)

# 创建主窗口
root = tk.Tk()
root.title("客户端")

# 左侧框架,包含服务器IP输入框和连接按钮
left_frame = tk.Frame(root)
left_frame.pack(side=tk.LEFT, padx=10, pady=10)

ip_label = tk.Label(left_frame, text="服务器IP:")
ip_label.pack(pady=5)
ip_entry = tk.Entry(left_frame)
ip_entry.pack(pady=5)

connect_button = tk.Button(left_frame, text="连接", command=connect)
connect_button.pack(pady=10)

# 中间框架,包含聊天框
middle_frame = tk.Frame(root)
middle_frame.pack(side=tk.LEFT, padx=10, pady=10)

chat_box = scrolledtext.ScrolledText(middle_frame, width=40, height=20)
chat_box.pack(padx=10, pady=10)

input_box = tk.Entry(middle_frame, width=30)
input_box.pack(pady=10)
input_box.bind("<Return>", send_message)

send_button = tk.Button(middle_frame, text="发送", command=send_message)
send_button.pack(pady=10)

# 右侧框架,包含在线用户列表
right_frame = tk.Frame(root)
right_frame.pack(side=tk.LEFT, padx=10, pady=10)

user_list_label = tk.Label(right_frame, text="在线用户列表")
user_list_label.pack(pady=5)

user_listbox = tk.Listbox(right_frame, width=20, height=20)
user_listbox.pack(padx=10, pady=10)

# 运行主循环
root.mainloop()
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 中文实名注册

本版积分规则

小黑屋|东台市机器人学会 ( 苏ICP备2021035350号-1;苏ICP备2021035350号-2;苏ICP备2021035350号-3 )

GMT+8, 2025-3-14 23:19 , Processed in 0.040514 second(s), 28 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表