基于Python Tkiner、thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信

基于Python Tkiner、thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信

基于Python Tkiner、thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信
完整代码下载地址:
运行效果图
服务端

www.zeeklog.com  - 基于Python Tkiner、thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信


客户端

www.zeeklog.com  - 基于Python Tkiner、thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信


客户端源代码

# codeing=utf-8
# @Time    : 2022-09-05
# @Site    :
# @Title   : Python中创建TCP服务器与客户端进行通信:Tk、thread与socket组合。
# @Url     :
# @Details : Python中创建TCP服务器与客户端进行通信:Tk、thread与socket组合。
# @Other   : OS X 10.14.6
#            Python 3.8
#            VSCode
###################################
# Python中创建TCP服务器与客户端进行通信:Tk、thread与socket组合。
###################################


import json
import random
import socket
import sys
import threading
import tkinter as tk
from tkinter import messagebox  # 导入提示窗口包

CHATCONTENT = 'chatcontent'  # 聊天内容
CHAT_EXIT = '|exit|'  # 退出聊天室
CHAT_USERS = 'chatusers'  # 聊天室用户列表
CHAT_REG_USERNAME = 'reg_username'  # 注册用昵称
CHAT_ONETOONE = 'onetoone'  # 私聊标识


class Gui_Client:
    '''
    聊天室客户端GUI构建
    '''

    def __init__(self):
        self.clist = {}  # 存放接入的socket客户端 以客户端用户名保存为字典
        self.namelist = list()  # 存放tk.listbox中的用户名称列表
        self.t = 0
        self.go()

    def go(self):
        '''
        构建GUI
        '''
        self.root = tk.Tk()  # 整个窗口
        self.root.title("欢迎光临Python江湖大佬聊天室客户端 1.0 By Python代码大全")
        self.info_frame = tk.Frame(self.root)  # 存放用户列表,聊天室交流信息部件
        self.info_frame.pack(fill=tk.X, side=tk.TOP)
        self.server_frame = tk.LabelFrame(
            self.root, text="聊天室设置", padx=5, pady=5)  # 存放聊天室服务器设置相关信息部件,服务器启动,暂停按钮。
        self.server_frame.pack(fill=tk.X, side=tk.TOP)

        # 用户列表框
        self.name_var = tk.StringVar()  # 绑定listbox的列表值
        self.lb = tk.Listbox(self.info_frame, listvariable=self.name_var, width=20, selectmode=tk.EXTENDED)
        self.lb.bind('<ButtonRelease-1>', self.onetoonethat)  # 绑定鼠标左键点击事件。
        self.lb.pack(fill=tk.Y, side=tk.LEFT)

        # test 测试列表用
        # self.name_var.set(('aa', 'bb', 'cc', 'dd', 'ee'))

        # 创建打印聊天信息的text
        # 分别创建一个横向,一个坚向的滚动条,
        self.ybar = tk.Scrollbar(self.info_frame)
        self.ybar.pack(fill=tk.Y, side=tk.RIGHT)
        # self.xbar = tk.Scrollbar(self.info_frame, orient=tk.HORIZONTAL)  # orient=tk.HORIZONTAL表示为坚向滚动
        # self.xbar.pack(fill=tk.X, side=tk.BOTTOM, )

        self.out = tk.Text(self.info_frame, width=80, font=("Symbol", 14), yscrollcommand=self.ybar.set, )
        insert_text(self.out, '欢迎光临Python江湖聊天室!')
        self.out.pack(fill=tk.Y, side=tk.LEFT)

        self.top_server = tk.Frame(self.server_frame, )
        self.top_server.pack(fill=tk.X, side=tk.TOP)

        # 设置IP文本框
        self.ip_var = tk.StringVar()
        self.ip_var.set('192.168.0.88')
        self.ip_entry = tk.Entry(
            self.top_server, textvariable=self.ip_var, width=12)
        self.ip_entry.pack(fill=tk.X, side=tk.LEFT)
        # 设置端口文本框
        self.port_var = tk.IntVar()
        self.port_var.set(18888)
        self.port_entry = tk.Entry(
            self.top_server, textvariable=self.port_var, width=5)
        self.port_entry.pack(side=tk.LEFT)

        self.start_btn = tk.Button(
            self.top_server, text="连接服务器", width=18, command=self.client_Start).pack(side=tk.LEFT)

        self.down_server = tk.Frame(self.server_frame, )
        self.down_server.pack(fill=tk.X, side=tk.BOTTOM)
        # 聊天窗口
        self.that_var = tk.StringVar()
        self.that_var.set('拜见各位python江湖大佬!')
        self.that = tk.Entry(
            self.down_server, textvariable=self.that_var, width=40)
        self.that.pack(fill=tk.X, side=tk.LEFT)

        # 信息发送按钮
        self.end_btn = tk.Button(
            self.down_server, text="发送消息", width=18, command=self.sendMsg).pack(side=tk.LEFT)

        self.root.protocol('WM_DELETE_WINDOW', self.close_window)
        self.root.mainloop()

    def close_window(self):
        """
        窗口关闭,关闭所有连接
        :return:
        """
        print('窗口准备开始关闭************')
        if self.t:
            data = {'protocol': CHAT_EXIT, 'data': '|exit|'}
            data1 = json.dumps(data)
            try:
                self.t.s.send(data1.encode('utf-8'))
                self.root.destroy()
            except:
                self.root.destroy()
                sys.exit()
            # if self.t.send_json(data):
            #     print('已发送退出聊天室的申请')
            # else:
            #     print("提示", "请先连接服务器再尝试聊天.")
            # self.root.destroy()
        else:
            self.root.destroy()

    def client_Start(self):
        '''
        启动客户端
        '''

        try:
            self.t = TcpClient(self.ip_var.get(), self.port_var.get(), self.name_var, self.namelist, self.out,
                               self.clist, getName())
            self.t.setDaemon(True)  # 这里很重要,不加程序界面会卡死!
            self.t.start()
            insert_text(self.out, "线程开始————————————\n")
            print('线程开始————————————')
        except Exception as e:
            messagebox.showinfo("提示", "服务器没有开启或无法连接!")
            print(e, '服务器没有开启或无法连接')

    def sendMsg(self):
        '''
        这里发送消息,可以对消息进行判断

        私聊内容 头部应该包括 @+昵称,用来判断是否发送私聊。
        '''
        msg = self.that.get()  # 获取聊天窗口里的消息

        # 私聊判断,组装私聊的json并发送
        if msg.find("@") == 0:  # 如果是私聊
            data = retOneToOneJsonData(msg)
            outmsg = '你悄悄的对'+data['name']+'说到:'+data['data']
            if self.t:
                if self.t.send_json(data):
                    insert_text(self.out,outmsg)

        else:
            # 公共聊天信息发送
            data = {'protocol': CHATCONTENT, 'data': msg}
            if self.t:
                if self.t.send_json(data):
                    insert_text(self.out, msg)
                else:
                    print("提示", "请先连接服务器再尝试聊天.")
            else:
                messagebox.showinfo("提示", "请先连接服务器再尝试聊天.")
                print("提示", "请先连接服务器再尝试聊天.")

    def onetoonethat(self, event):
        '''
        列表中点击名称进行私聊
        '''
        items = self.lb.curselection()
        for k in items:
            print(self.lb.get(k))
            firstmsg = '@' + self.lb.get(k) + ' '  # 私聊标识 @昵称+空格
            msg = '你好,可以私聊一会吗?'
            self.that_var.set(firstmsg + msg)


class TcpClient(threading.Thread):
    def __init__(self, addr, port, name_var, namelist, out, clist, name):
        threading.Thread.__init__(self)
        self.addr = addr
        self.port = port
        self.name_var = name_var
        self.namelist = namelist  # 在线列表
        self.out = out
        self.clist = clist
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.connect((self.addr, self.port))
        self.stop_flag = False
        self.name = name
        self.msgdata = ''
        self.isOk = 1

    def run(self):
        self.inThat()  # 进入聊天室

    # 发送客户端用户名,保存在服务器端列表中
    # 此处还有修改昵称等功能,若昵称相同服务器则会返回一个新昵称,然后用户自己可以再次修改
    def inThat(self):
        while not self.stop_flag:
            if self.isOk:
                self.isNameOk()
            try:
                msg = self.rece_json(self.s.recv(1024).decode())
                print(type(msg))
                if msg['protocol'] == CHAT_EXIT:  # 退出断开连接
                    insert_text(self.out, msg)
                    break
                if msg['protocol'] == CHAT_USERS:  # 接收新的用户列表
                    print('接收用户列表')
                    self.namelist.clear()
                    self.namelist = msg['data']
                    self.name_var.set(self.namelist)
                    print('保存用户列表成功')
                if msg['protocol'] == CHATCONTENT:  # 接收聊天内容
                    insert_text(self.out, msg['data'])
                    print('接收服务器的消息:', msg['data'])
            except Exception as e:
                print('收消息线程已关闭', e)
                break
        msg = '服务器已断开,或是您已退出聊天室。'
        insert_text(self.out, msg)
        self.stop()

    def isNameOk(self):
        '''
        用户昵称验证方法
        '''
        # 发送昵称到服务器
        print('验证昵称')
        while True:
            if self.isOk:
                usernamedata = {'protocol': CHAT_REG_USERNAME, 'data': self.name}
                self.send_json(usernamedata)  # 发送昵称到服务器验证
                self.isOk = 0

            tempjson = self.rece_json(self.s.recv(1024))
            if tempjson['protocol'] == CHAT_REG_USERNAME:  # 昵称正常的话跳出昵称验证的循环,开始正常接收消息
                self.name = getName()
                self.isOk = 1
                print('验证昵称失败,重新发送了新昵称验证')
            elif tempjson['protocol'] == CHAT_USERS:  # 接收用户列表并展示
                print('接收用户列表')
                self.namelist.clear()
                self.namelist = tempjson['data']
                self.name_var.set(self.namelist)
                print('验证昵称成功,保存用户列表成功')
                break

    def send_json(self, msg):
        '''
        发送json格式的消息到服务器
        :param msg: str 消息内容
        :return: bool
        '''

        data = json.dumps(msg)
        try:
            self.s.send(data.encode('utf-8'))
            return 1
        except:
            messagebox.showinfo("提示", "请先连接服务器再尝试聊天.")
            return 0

    def rece_json(self, data):
        '''
        :param data: 收到的json数据
        :return:python对象
        '''
        jsondata = json.loads(data)
        print(jsondata, type(jsondata))
        return jsondata

    def stop(self):
        self.s.close()
        self.stop_flag = True


def retOneToOneJsonData(msg):
    '''
    返回私聊发送的数据
    '''

    # 获取用户名
    name = msg.split(" ")[0].lstrip("@")
    # 获取聊天内容
    skey = msg.split(" ")[0]
    data = msg.replace(skey+" ", "")

    return {'protocol': CHAT_ONETOONE, 'data': data, 'name': name, }


def insert_text(out, msg):
    '''
    添加聊天记录到text部件。
    :param msg: str
    :return:
    '''
    out.insert(tk.END, msg + '\n')
    out.see(tk.END)


def main():
    Gui_Client()

    # 私聊发送测试
    # print(retOneToOneJsonData('@aaa hahah,hahah hfhfh oasdf @'))


def getName():
    '''
    生成聊天室的昵称
    '''
    n = 'python大佬'
    id = random.randint(999, 9999)
    name = n + str(id)
    return name


if __name__ == '__main__':
    main()

完整代码下载地址:

Read more

【大模型科普】AIGC技术发展与应用实践(一文读懂AIGC)

【大模型科普】AIGC技术发展与应用实践(一文读懂AIGC)

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能(AI)通过算法模拟人类智能,利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络(如ChatGPT),经海量数据训练后能完成文本生成、图像创作等复杂任务,显著提升效率,但面临算力消耗、数据偏见等挑战。当前正加速与教育、科研融合,未来需平衡技术创新与伦理风险,推动可持续发展。 文章目录 * 一、AIGC概述 * (一)什么是AIGC * (二)AIGC与大模型的关系 * (三)常见的AIGC应用场景 * (四)AIGC技术对行业发展的影响 * (五)AIGC技术对职业发展的影响 * (六)常见的AIGC大模型工具 * (七)AIGC大模型的提示词 * 二、文本类AIGC应用实践 * (一)案例1:与DeepSeek进行对话 * (二)案例2:与百度文心一言进行对话 * (三)案例3:使用讯飞智文生成PPT

intv_ai_mk11GPU部署:24GB显存运行Llama中型模型的CUDA版本与驱动适配指南

intv_ai_mk11 GPU部署:24GB显存运行Llama中型模型的CUDA版本与驱动适配指南 1. 环境准备与系统要求 1.1 硬件配置要求 要在24GB显存的GPU上顺利运行intv_ai_mk11模型,您的设备需要满足以下最低配置: * GPU显存:最低24GB(推荐NVIDIA RTX 3090/4090或A100 40GB) * 系统内存:至少32GB RAM * 存储空间:50GB可用空间(用于模型权重和依赖项) * CPU:支持AVX指令集的现代多核处理器 1.2 软件环境要求 * 操作系统:Ubuntu 20.04/22.04 LTS(推荐)或CentOS 7+ * CUDA版本:11.7或11.8(与驱动版本匹配) * 驱动版本:515.65.

实体关系图谱构建:从零到一指南,云端Neo4j+GPU加速

实体关系图谱构建:从零到一指南,云端Neo4j+GPU加速 引言:为什么你需要云端Neo4j? 想象一下,你正在整理一个庞大的家族族谱,手写记录需要好几天,而用电子表格可能只需要几小时——这就是传统数据库与图数据库的区别。当你的知识图谱项目遇到性能瓶颈(比如单机处理全量数据要2天),云端Neo4j配合GPU加速能帮你把时间压缩到3小时,还能实时可视化展示复杂关系。 Neo4j是目前最流行的图数据库,特别擅长处理"谁认识谁""什么属于什么"这类关系密集型任务。本指南将带你从零开始: 1. 理解实体关系图谱的核心概念 2. 快速部署云端Neo4j环境 3. 用GPU加速数据处理 4. 生成可视化关系网络 即使你是刚接触知识图谱的小白,跟着步骤操作也能在1小时内完成首次图谱构建。 1. 环境准备:5分钟搞定云端部署 1.1 选择适合的镜像 在ZEEKLOG星图镜像广场搜索"Neo4j GPU",选择预装以下组件的镜像: - Neo4j 5.

多模态融合:结合RetinaFace+CurricularFace与语音识别构建智能交互系统

多模态融合:结合RetinaFace+CurricularFace与语音识别构建智能交互系统 你是否也遇到过这样的问题:团队想做一个能“看脸”又能“听声”的智能交互系统,比如门禁系统既能识别人脸又能验证声音,或者客服机器人能通过摄像头和麦克风同时感知用户情绪?听起来很酷,但真正动手时却发现——人脸模型和语音模型像是两个世界的东西,部署方式五花八门,环境依赖冲突不断,GPU资源调度混乱,最后集成起来像拼图一样费劲。 别担心,这正是我们今天要解决的问题。作为一名在AI领域摸爬滚打多年的技术老兵,我最近也在帮一个创新团队搭建类似的多模态系统。他们原本打算分别用两套服务器跑人脸识别和语音识别,结果不仅成本翻倍,数据同步还经常出错。后来我们换了个思路:用统一的AI镜像平台,把RetinaFace + CurricularFace 和语音识别模型一起部署到同一个GPU环境中,实现了“一次部署、多模态协同”。 这篇文章就是我实战经验的完整复盘。我会带你从零开始,一步步搭建这个融合视觉与听觉的智能交互系统。即使你是AI新手,只要跟着操作,也能在5分钟内完成核心功能的部署,并理解背后的运行逻辑。更