Python学习总结

客户端与服务端聊天窗口

服务端
导入
wxPython 用于创建图形界面。
socket 用于网络通信,AF_INET 是 IPv4 地址族,SOCK_STREAM 表示流式套接字(TCP)。

利用wxPython 创建图形界面,并通过 socket 与服务器通信。

主要功能:

  • 连接服务器。
  • 发送和接收消息。
  • 断开连接。
  • 界面上有文本框和按钮来操作。
  • wxPython 处理 UI 部分,socket 处理网络通信。
import threading
from threading import main_thread, Thread
#coding UTF-8
import self
import wx
import time
from socket import socket,AF_INET,SOCK_STREAM

class YsjServer(wx.Frame):
//通过继承 wx.Frame,我们可以创建一个带有窗口的应用程序。
    def __init__(self):
        wx.Frame.__init__(self,None,id=1002,title='某工作室界面')
        # 创建面板对象
        pl = wx.Panel(self)
        # 面板中放盒子
        box = wx.BoxSizer(wx.VERTICAL)
        # 可伸缩的网格布局
        fgz1 = wx.FlexGridSizer(wx.HSCROLL)

        start_server_btn = wx.Button(parent=pl, size=(133,40), label='启动')
        record_btn = wx.Button(parent=pl, size=(133, 40), label='保存聊天记录')
        stop_server_btn = wx.Button(parent=pl, size=(133, 40), label='离开')

        fgz1.Add(start_server_btn, 1, wx.TOP)
        fgz1.Add(record_btn, 1, wx.TOP )
        fgz1.Add(stop_server_btn, 1, wx.TOP)
        # (可伸缩的网络布局)添加到box中
        box.Add(fgz1, 1, wx.ALIGN_CENTRE)

        # 只读文本框
        self.show_text = wx.TextCtrl(pl, size=(400, 410), style=wx.TE_MULTILINE | wx.TE_READONLY)
        box.Add(self.show_text, 1, wx.ALIGN_CENTRE)

        #盒子放面板
        pl.SetSizer(box)



        '--------界面绘制--------'
        '-----------服务器功能------'
        self.isOn=False
        self.host_port=('',8888)
        # 创建socket对象
        self.server_socket = socket(AF_INET, SOCK_STREAM)
        # 绑定IP地址和端口
        self.server_socket.bind(self.host_port)
        # 监听
        self.server_socket.listen(5)
        # 创建一个字典,存储与客户端对话的会话线程
        self.session_thread_dict = {}  # key-value {客户端的名称key:会话线程value}

        # 当鼠标点击“启动服务”按钮时,要执行的操作
        self.Bind(wx.EVT_BUTTON,self.start_server,start_server_btn)
        #'保存聊天记录'
        self.Bind(wx.EVT_BUTTON, self.save_record,record_btn )
        # '断开'
        self.Bind(wx.EVT_BUTTON, self.stop_server, stop_server_btn)

    def stop_server(self, event):
        print('服务器已停止服务')
        self.isOn = False

    def save_record(self, event):
        record_data = self.show_text.GetValue()
        with open('record.log', 'w', encoding='utf-8') as file:
            file.write(record_data)

    def start_server(self,event):
        #判断是否启动
        if not self.isOn:
            #启动
            self.isOn=True
            #创建主线程对象
            main_thread=threading.Thread(target=self.do_work())
            #设置守护线程,父线程执行结束,子线程也自动关闭
            main_thread.demon=True

            #启动
            main_thread.start()

    def do_work(self):
         while self.isOn:
             #接收客户端的连接请求
            session_socket,client_addr=self.server_socket.accept()
            #客户端发送连接请求之后,发送过来的第一条数据为客户端的名称,作为键
            user_name=session_socket.recv(1024).decode('utf-8')
            #创建绘画线程对象
            session_thread=SessionThread(session_socket,user_name,self)
            self.session_thread_dict[user_name]=session_thread
            session_thread.start()
            self.show_info_and_send_client('服务器通知', f'欢迎{user_name}进入聊天室!',time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
                                           )

         self.server_socket.close()

    def show_info_and_send_client(self, data_source, data, date_time):
        # 字符串操作
        send_data = f'{data_source}:{data}\n时间:{date_time}'
        # 只读文本框
        self.show_text.AppendText('-' * 40 + '\n' + send_data + '\n')
        # 给每一个客户端都发送一次
        for client in self.session_thread_dict.values():
            # 如果当前的会话处于开启状态
            if client.isOn:
                client.client_socket.send(send_data.encode('utf-8'))


class SessionThread(threading.Thread):
    def __init__(self,client_socket,user_name,server):
        # 调用父类的初始化方法
        threading.Thread.__init__(self)
        self.client_socket = client_socket
        self.user_name = user_name
        self.server = server
        self.isOn = True  # 会话线程是否启动,当创建SessionThread对象时会话线程即启动

    def run(self) -> None:
        print(f'客户端:{self.user_name}已经和服务器连接成功,服务器启动一个会话线程')
        while self.isOn:
            # 从客户端接收数据 存储到data中
            data = self.client_socket.recv(1024).decode('utf-8')
            # 如果客户端点击断开按钮,先给服务器发送一句话, 消息自定义  Y-disconnect-SJ 自定义的结束词儿
            if data == 'Y-disconnect-SJ':
                self.isOn = False
                self.server.show_info_and_send_client('服务器通知',f'{self.user_name}离开聊天室',
                                                      time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))

            else:
                # 其它聊天信息显示给所有的客户端,包含服务器也显示
                # 调用刚才编写的方法
                self.server.show_info_and_send_client(self.user_name, data,time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
        # 关闭 socket
        self.client_socket.close()
if __name__ == '__main__':
    app=wx.App()
    server =YsjServer()
    server.Show()
    app.MainLoop()

客户端

import wx
#coding UTF-8
from socket import  socket,AF_INET,SOCK_STREAM

class YsJClient(wx.Frame):
    def __init__(self, client_name):
        #调用父类的初始化方法
        #None:表示没有父级窗口
        #id 表示窗口编号
        #pos  窗体打开的位置
        #size 窗体的大小,单位像素
        wx.Frame.__init__(self,None, id=1001, title=client_name + '的客户端界面',pos=wx.DefaultPosition, size=(400, 450))
        #创建面板对象
        pl = wx.Panel(self)
        #面板中放盒子
        box = wx.BoxSizer(wx.VERTICAL)
        # 可伸缩的网格布局
        fgz1 = wx.FlexGridSizer(wx.HSCROLL)
        # 水平方向布局

        # 创建两个按钮
        conn_btn = wx.Button(parent=pl, size=(200, 40), label='连接')
        dis_conn_btn = wx.Button(parent=pl, size=(200, 40), label='断开')

        # 把两个按钮放到可伸缩的网格布局
        fgz1.Add(conn_btn, 1, wx.TOP | wx.LEFT)
        fgz1.Add(dis_conn_btn, 1, wx.TOP | wx.RIGHT)

        # (可伸缩的网络布局)添加到box中
        box.Add(fgz1, 1, wx.ALIGN_CENTRE)

        #只读文本框
        self.show_text=wx.TextCtrl(pl,size=(400,210),style=wx.TE_MULTILINE|wx.TE_READONLY)
        box.Add(self.show_text,1,wx.ALIGN_CENTRE)

        #创建聊天文本框
        self.chat_text = wx.TextCtrl(pl, size=(400, 120), style=wx.TE_MULTILINE)
        box.Add(self.chat_text, 1, wx.ALIGN_CENTRE)

        #可绳索网格布局
        fgz1 = wx.FlexGridSizer(wx.HSCROLL)

        #两个按钮
        reset_btn = wx.Button(parent=pl, size=(200, 40), label='重置')
        send_btn = wx.Button(parent=pl, size=(200, 40), label='发送')
        fgz1.Add(reset_btn, 1, wx.TOP | wx.LEFT)
        fgz1.Add(send_btn, 1, wx.TOP | wx.RIGHT)

        # (可伸缩的网络布局)添加到box中
        box.Add(fgz1, 1, wx.ALIGN_CENTRE)

        pl.SetSizer(box)


        '--------客户端界面绘制--------'
        self.Bind(wx.EVT_BUTTON, self.connect_to_server, conn_btn)
        self.client_name=client_name
        self.isConnected=False
        self.client_socket=None
        #发送绑定
        self.Bind(wx.EVT_BUTTON, self.send_to_server, send_btn)
        #断开绑定
        self.Bind(wx.EVT_BUTTON, self.dis_conn_to_server, dis_conn_btn)
        # 重置绑定
        self.Bind(wx.EVT_BUTTON, self.reset, reset_btn)
    def reset(self,event):
        self.chat_text.Clear()

    def dis_conn_to_server(self,event):
        self.client_socket.send('Y-disconnect-SJ'.encode('utf-8'))
        self.isconnected=False

    def send_to_server (self,event):
        if self.isConnected:
            input_data=self.chat_text.GetValue()
            if input_data!='':
                self.client_socket.send(input_data.encode('utf-8'))
                self.chat_text.SetValue('')


    def connect_to_server(self, event):
        print(f'客户端{self.client_name}连接服务器成功')
        if not self.isConnected:
            server_host_port=('127.0.0.1',8888)
            #创建socket对象
            self.client_socket=socket(AF_INET,SOCK_STREAM)
            #发送请求
            self.client_socket.connect(server_host_port)
            import threading
            # 只要连接成功,发送一条数据
            self.client_socket.send(self.client_name.encode('utf-8'))
            # 启动一个线程,客户端的线程与服务器的会话线程进行会话
            client_thread = threading.Thread(target=self.recv_data)
            # 设置成守护线程, 窗体关掉,子线程也结束了
            client_thread.daemon = True
            # 修改一下连接状态
            self.isConnected = True
            # 启动线程
            client_thread.start()
    def recv_data(self):
        while self.isConnected:
            data=self.client_socket.recv(1024).decode('utf-8')
            # 只读文本框
            self.show_text.AppendText('-' * 40 + '\n' + data + '\n')


        '-----------服务器功能------'
if __name__ == '__main__':
    app=wx.App()
    name=input('请输入客户端名称')
    client =YsJClient(name)

    client.Show()
    app.MainLoop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/975660.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

演示基于FPGA的视频图像去雾处理效果

我近期用FPGA开发板做了一个视频图像去雾算法模块,用于验证其能否在不进行帧缓冲的情况下实现去雾功能。 去雾算法来自一篇技术资料(私信提供篇名),其基础是近似的大气光模型。 1 算法原理概要 借助RGB直角坐标空间中的光矢量分…

UE_C++ —— Gameplay Tags

目录 一,Defining Gameplay Tags Adding Tags in Project Settings Importing Tags from Data Table Assets Defining Tags with C 二,Using Defined Gameplay Tags Applying Tags to Objects Evaluating Tags with Conditional Functions 三&am…

计算机视觉算法实战——三维重建(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ 1. 三维重建领域简介 三维重建(3D Reconstruction)是计算机视觉的核心任务之一,旨在通过多视角图像、视频…

Spring5框架八:整合Mybatis

精心整理了最新的面试资料&#xff0c;有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 1、导入相关的jar包 <dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>…

AI学习第一天-什么是AI

AI的发展可以被分为四次浪潮&#xff0c;这包括符号主义、机器学习与神经网络&#xff0c;以及深度学习。在这些发展中&#xff0c;深度学习凭借其在处理非结构化复杂数据、强大的学习能力和可解释性方面的优势备受关注。深度学习技术的应用不仅提升了AI系统的性能&#xff0c;…

redis-bitmap使用场景

bitmap原理 Bitmap&#xff08;位图&#xff09;是一种基于二进制位的数据结构&#xff0c;用于高效地存储和操作大量的布尔值 可以对单个位进行读写操作 demo package org.example;import org.redisson.Redisson; import org.redisson.api.RBitSet; import org.redisson.ap…

华为 网络安全 认证

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 华为 网络安全 认证&#xff1a;保障信息安全的重要一环 在数字化时代的今天&#xff0c;网络安全成为了企业和个人都需要高度重视的问题。尤其是在企业信息化的…

ubuntu22.04连接github无法访问的问题

目录 说明安装 说明 此方案只针对虚拟机, 如果是云服务器(毕竟是官方维护, github还是能访问到的)多试几次肯定能够访问到的. 国内我们无法访问外网, 所以我们目前能够访问外网的途径基本上只能开佳速器. 所以我们需要选择一款加速器来帮助我们访问外网, 目前市面上很多佳速器…

【Research Proposal】基于提示词方法的智能体工具调用研究——难点

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;一、难点分析1. 提示词方法的多样性和组合问题2. 智能体工具调用的准确性和效率问题3. 多模态任务中的复杂性问题 &#x1f4af;二、解决思路与策略&#x1f…

Linux搭建Nginx直播流媒体服务RTMP/RTSP转Http-flv视频浏览器在线播放/Vue/Java/ffmpeg

参考文章&#xff1a; https://blog.csdn.net/whatareyouding/article/details/144317654 https://www.cnblogs.com/Gredae/p/18362900 https://www.cnblogs.com/kn-zheng/p/17422707.html https://blog.51cto.com/u_16099344/10281495 https://www.tulingxueyuan.cn/tlzx/jsp…

智慧教室与无纸化同屏技术方案探讨与实现探究

引言 随着教育信息化的不断发展&#xff0c;智慧教室和无纸化同屏技术逐渐成为提升教学效率和质量的重要手段。大牛直播SDK凭借其强大的音视频处理能力和丰富的功能特性&#xff0c;在智慧教室和无纸化同屏领域积累了众多成功案例。本文将深入探讨基于大牛直播SDK的智慧教室、…

自制操作系统前置知识汇编学习

今天要做什么&#xff1f; 为了更好的理解书中内容&#xff0c;需要学习下进制分析和汇编。 汇编语言其实应该叫叫机器指令符号化语言&#xff0c;目前的汇编语言是学习操作系统的基础。 一&#xff1a;触发器 电路触发器的锁存命令默认是断开的&#xff0c;是控制电路触发器…

嘉立创EDA一自画元件及其封装

目录 一、创建元件 &#xff08;1&#xff09;新建元件。 &#xff08;2&#xff09;绘制元件。 二、绘制封装 &#xff08;1&#xff09;新建封装。 &#xff08;2&#xff09;绘制封装。 三、关联元件与封装 四、封装设计注意事项 在嘉立创&#xff08;JLCPCB&#xff…

《深度学习实战》第2集-补充:卷积神经网络(CNN)与图像分类 实战代码解析和改进

以下是对《深度学习实战》第2集中 CIFAR-10 数据集 使用卷积神经网络进行图像分类实战 代码的详细分析&#xff0c;并增加数据探索环节&#xff0c;同时对数据探索、模型训练和评估的过程进行具体说明。所有代码都附上了运行结果配图&#xff0c;方便对比。 《深度学习实战》第…

dataframe如何在末尾添加多行

如果要在pandas的dataframe中添加多行该如何实现&#xff1f;可通过以下常见方式在DataFrame末尾添加&#xff1a; ### 方法一&#xff1a;使用loc索引器 利用loc索引器分两次操作来添加两行数据。假设已有DataFrame对象df&#xff0c;要添加的两行数据分别存储在字典new_row…

使用 DeepSeek 生成流程图、甘特图与思维导图:结合 Typora 和 XMind 的高效工作流

在现代工作与学习中&#xff0c;可视化工具如流程图、甘特图和思维导图能够极大地提升信息整理与表达的效率。本文将详细介绍如何使用 DeepSeek 生成 Mermaid 文本&#xff0c;结合 Typora 快速生成流程图和甘特图&#xff0c;并通过 Markdown 格式生成思维导图&#xff0c;最终…

插入排序(详解)c++

插⼊排序(Insertion Sort)类似于玩扑克牌插牌过程&#xff0c;每次将⼀个待排序的元素按照其关键字⼤⼩插⼊到前⾯已排好序的序列中&#xff0c;按照该种⽅式将所有元素全部插⼊完成即可 算法思想&#xff1a; 把待排序元素插入到已排序的序列中。想象一下一张一张整理扑克牌的…

【大模型】蓝耘智算云平台快速部署DeepSeek R1/R3大模型详解

目录 一、前言 二、蓝耘智算平台介绍 2.1 蓝耘智算平台是什么 2.2 平台优势 2.3 应用场景 2.4 对DeepSeek 的支持 2.4.1 DeepSeek 简介 2.4.2 DeepSeek 优势 三、蓝耘智算平台部署DeepSeek-R1操作过程 3.1 注册账号 3.1.1 余额检查 3.2 部署DeepSeek-R1 3.2.1 获取…

ai-financial-agent - 为金融投资打造的AI代理

探索人工智能在投资研究中的应用。本项目仅用于**教育**目的&#xff0c;不用于真实交易或投资。 作者声明&#xff1a; 本项目仅用于教育和研究目的。 不用于真实交易或投资不提供任何保证或担保过去的表现并不代表未来的结果Creator 对经济损失不承担任何责任咨询财务顾问…

基于keepalived的Nginx高可用架构

一、概述 Keepalived 是一个基于 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;协议 的高可用性解决方案&#xff0c;为了解决静态路由器出现的单点故障问题&#xff0c;它能偶保证网络的不间断、稳定的运行。 二、核心功能 IP 漂移&#xff08;VIP&…