python:并发编程(二十四)

这篇具有很好参考价值的文章主要介绍了python:并发编程(二十四)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本文将和大家一起探讨python并发编程的实际项目:win图形界面应用(篇六,共八篇),系列文章将会从零开始构建项目,并逐渐完善项目,最终将项目打造成适用于高并发场景的应用。

本文为python并发编程的第二十四篇,上一篇文章地址如下:

python:并发编程(二十三)_Lion King的博客-CSDN博客

下一篇文章地址如下:

python:并发编程(二十五)_Lion King的博客-CSDN博客

一、协议界面设计

1、TCP Client界面

设计 TCP Client 界面可以根据需求和设计风格进行定制。以下是一种简单的设计示例,用于展示 TCP Client 的基本元素和布局:

(1)标签和输入框:用于输入服务器的 IP 地址和端口号。

(2)连接按钮:单击该按钮将与服务器建立连接。

(3)发送区域:包含文本框和发送按钮,用于输入要发送给服务器的消息和发送消息的操作。

(4)接收区域:用于显示从服务器接收到的消息。

下面是一个示例代码,展示了如何创建一个简单的 TCP Client 界面:

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import socket
import threading

class TCPClientFrame(ttk.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_widgets()

    def create_widgets(self):
        # IP 地址标签和输入框
        ip_label = ttk.Label(self, text="服务器 IP 地址:")
        ip_label.grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
        self.ip_entry = ttk.Entry(self)
        self.ip_entry.grid(row=0, column=1, padx=5, pady=5)

        # 端口号标签和输入框
        port_label = ttk.Label(self, text="服务器端口号:")
        port_label.grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
        self.port_entry = ttk.Entry(self)
        self.port_entry.grid(row=1, column=1, padx=5, pady=5)

        # 连接按钮
        connect_button = ttk.Button(self, text="连接", command=self.connect_to_server)
        connect_button.grid(row=2, column=0, columnspan=2, padx=5, pady=5)

        # 发送区域
        send_label = ttk.Label(self, text="发送消息:")
        send_label.grid(row=3, column=0, padx=5, pady=5, sticky=tk.W)
        self.send_entry = ttk.Entry(self)
        self.send_entry.grid(row=3, column=1, padx=5, pady=5)
        send_button = ttk.Button(self, text="发送", command=self.send_message)
        send_button.grid(row=4, column=0, columnspan=2, padx=5, pady=5)

        # 接收区域
        receive_label = ttk.Label(self, text="接收消息:")
        receive_label.grid(row=5, column=0, padx=5, pady=5, sticky=tk.W)
        self.receive_text = tk.Text(self, height=5, width=30)
        self.receive_text.grid(row=5, column=1, padx=5, pady=5)

        # 初始化 TCP 连接对象和接收线程
        self.tcp_client = None
        self.receive_thread = None

    def connect_to_server(self):
        # 获取服务器 IP 地址和端口号
        ip = self.ip_entry.get()
        port = int(self.port_entry.get())

        # 建立 TCP 连接
        try:
            self.tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.tcp_client.connect((ip, port))
            messagebox.showinfo("连接成功", "成功连接到服务器")
            # 启动接收线程
            self.receive_thread = threading.Thread(target=self.receive_messages)
            self.receive_thread.start()
        except Exception as e:
            messagebox.showerror("连接错误", str(e))
            self.tcp_client = None

    def send_message(self):
        # 获取要发送的消息
        message = self.send_entry.get()

        # 发送消息给服务器
        try:
            self.tcp_client.send(message.encode())
            self.receive_text.insert(tk.END, f"发送消息: {message}\n")
        except Exception as e:
            messagebox.showerror("发送错误", str(e))

        # 清空发送输入框
        self.send_entry.delete(0, tk.END)

    def receive_messages(self):
        while True:
            try:
                # 接收服务器消息
                message = self.tcp_client.recv(1024).decode()
                self.receive_text.insert(tk.END, f"接收消息: {message}\n")
            except Exception as e:
                # 出现错误时关闭连接并退出接收线程
                self.tcp_client.close()
                messagebox.showinfo("连接断开", "与服务器的连接已断开")
                break

if __name__ == "__main__":
    app = tk.Tk()
    app.title("TCP Client")
    tcp_client_frame = TCPClientFrame(app)
    tcp_client_frame.pack()
    app.mainloop()

每建立一个TCP连接,就会创建一个子线程。

2、将TCPclient界面嵌入到主界面中

import tkinter as tk
from tkinter import ttk
import socket
import threading
from tkinter import messagebox

class TCPClientFrame(ttk.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_widgets()

    def create_widgets(self):
        # IP 地址标签和输入框
        ip_label = ttk.Label(self, text="服务器 IP 地址:")
        ip_label.grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
        self.ip_entry = ttk.Entry(self)
        self.ip_entry.grid(row=0, column=1, padx=5, pady=5)

        # 端口号标签和输入框
        port_label = ttk.Label(self, text="服务器端口号:")
        port_label.grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
        self.port_entry = ttk.Entry(self)
        self.port_entry.grid(row=1, column=1, padx=5, pady=5)

        # 连接按钮
        connect_button = ttk.Button(self, text="连接", command=self.connect_to_server)
        connect_button.grid(row=2, column=0, columnspan=2, padx=5, pady=5)

        # 发送区域
        send_label = ttk.Label(self, text="发送消息:")
        send_label.grid(row=3, column=0, padx=5, pady=5, sticky=tk.W)
        self.send_entry = ttk.Entry(self)
        self.send_entry.grid(row=3, column=1, padx=5, pady=5)
        send_button = ttk.Button(self, text="发送", command=self.send_message)
        send_button.grid(row=4, column=0, columnspan=2, padx=5, pady=5)

        # 接收区域
        receive_label = ttk.Label(self, text="接收消息:")
        receive_label.grid(row=5, column=0, padx=5, pady=5, sticky=tk.W)
        self.receive_text = tk.Text(self, height=5, width=30)
        self.receive_text.grid(row=5, column=1, padx=5, pady=5)

        # 初始化 TCP 连接对象和接收线程
        self.tcp_client = None
        self.receive_thread = None

    def connect_to_server(self):
        # 获取服务器 IP 地址和端口号
        ip = self.ip_entry.get()
        port = int(self.port_entry.get())

        # 建立 TCP 连接
        try:
            self.tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.tcp_client.connect((ip, port))
            messagebox.showinfo("连接成功", "成功连接到服务器")
            # 启动接收线程
            self.receive_thread = threading.Thread(target=self.receive_messages)
            self.receive_thread.start()
        except Exception as e:
            messagebox.showerror("连接错误", str(e))
            self.tcp_client = None

    def send_message(self):
        # 获取要发送的消息
        message = self.send_entry.get()

        # 发送消息给服务器
        try:
            self.tcp_client.send(message.encode())
            self.receive_text.insert(tk.END, f"发送消息: {message}\n")
        except Exception as e:
            messagebox.showerror("发送错误", str(e))

        # 清空发送输入框
        self.send_entry.delete(0, tk.END)

    def receive_messages(self):
        while True:
            try:
                # 接收服务器消息
                message = self.tcp_client.recv(1024).decode()
                self.receive_text.insert(tk.END, f"接收消息: {message}\n")
            except Exception as e:
                # 出现错误时关闭连接并退出接收线程
                self.tcp_client.close()
                messagebox.showinfo("连接断开", "与服务器的连接已断开")
                break

class ProtocolTestApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("协议测试")
        self.geometry("400x300")

        self.notebook = ttk.Notebook(self)
        self.notebook.pack(fill="both", expand=True)

        self.create_menu()

    def create_menu(self):
        menu_bar = tk.Menu(self)

        # 创建客户端菜单和子菜单
        client_menu = tk.Menu(menu_bar, tearoff=0)
        client_menu.add_command(label="TCP Client", command=self.create_tcp_client_tab)
        client_menu.add_command(label="UDP Client", command=self.create_udp_client_tab)
        menu_bar.add_cascade(label="客户端", menu=client_menu)

        # 创建服务端菜单和子菜单
        server_menu = tk.Menu(menu_bar, tearoff=0)
        server_menu.add_command(label="TCP Server", command=self.create_tcp_server_tab)
        server_menu.add_command(label="UDP Server", command=self.create_udp_server_tab)
        menu_bar.add_cascade(label="服务端", menu=server_menu)

        # 将菜单栏配置到窗口
        self.config(menu=menu_bar)

    def create_tcp_client_tab(self):
        # 创建TCP Client的tab页
        tcp_client_frame = ttk.Frame(self.notebook)
        tcp_client_frame.pack(fill="both", expand=True)
        self.notebook.add(tcp_client_frame, text="TCP Client")

        # 创建关闭按钮
        close_button = ttk.Button(tcp_client_frame, text="×", width=8, command=lambda: self.close_tab(tcp_client_frame))
        close_button.place(relx=1.0, rely=0.0, anchor="ne")

        # 创建 TCP Client 的界面
        tcp_client = TCPClientFrame(tcp_client_frame)
        tcp_client.pack()

    def create_udp_client_tab(self):
        # 创建UDP Client的tab页
        udp_client_frame = ttk.Frame(self.notebook)
        udp_client_frame.pack(fill="both", expand=True)
        self.notebook.add(udp_client_frame, text="UDP Client")

        # 创建关闭按钮
        close_button = ttk.Button(udp_client_frame, text="×", width=8, command=lambda: self.close_tab(udp_client_frame))
        close_button.place(relx=1.0, rely=0.0, anchor="ne")

    def create_tcp_server_tab(self):
        # 创建TCP Server的tab页
        tcp_server_frame = ttk.Frame(self.notebook)
        tcp_server_frame.pack(fill="both", expand=True)
        self.notebook.add(tcp_server_frame, text="TCP Server")

        # 创建关闭按钮
        close_button = ttk.Button(tcp_server_frame, text="×", width=8, command=lambda: self.close_tab(tcp_server_frame))
        close_button.place(relx=1.0, rely=0.0, anchor="ne")

    def create_udp_server_tab(self):
        # 创建UDP Server的tab页
        udp_server_frame = ttk.Frame(self.notebook)
        udp_server_frame.pack(fill="both", expand=True)
        self.notebook.add(udp_server_frame, text="UDP Server")

        # 创建关闭按钮
        close_button = ttk.Button(udp_server_frame, text="×", width=8, command=lambda: self.close_tab(udp_server_frame))
        close_button.place(relx=1.0, rely=0.0, anchor="ne")

    def close_tab(self, frame):
        self.notebook.hide(frame)

if __name__ == "__main__":
    app = ProtocolTestApp()
    app.mainloop()

python:并发编程(二十四)

以上代码是在原有的 ProtocolTestApp 类的基础上进行了修改和扩展,主要实现了 TCP Client 界面的设计和功能。

ProtocolTestApp 类中,我们添加了一个新的方法 create_tcp_client_tab,用于创建 TCP Client 的选项卡。在该选项卡中,我们创建了一个 TCPClientFrame 对象,并将其添加到选项卡的 tcp_client_frame 中。

TCPClientFrame 是一个自定义的 tkinter Frame,用于显示 TCP Client 的界面和处理相关功能。在 TCPClientFrame 中,我们添加了一个 ttk.Entry 组件用于输入服务器的 IP 地址,一个 ttk.Button 组件用于连接服务器,一个 tkinter.Text 组件用于显示接收到的消息,以及一个 ttk.Entry 组件用于输入要发送的消息和一个 ttk.Button 组件用于发送消息。

在连接按钮的回调函数中,我们获取输入的 IP 地址并尝试与服务器建立连接。如果连接成功,我们创建一个新的线程来接收服务器发送的消息,并将其显示在接收文本框中。

发送按钮的回调函数中,我们获取输入的消息,并通过 TCP Client 的连接发送给服务器。

最后,通过修改 ProtocolTestApp 类的 create_tcp_client_tab 方法,将 TCPClientFrame 添加到 TCP Client 的选项卡中,从而实现了 TCP Client 界面的设计和功能。

整体而言,以上代码通过创建自定义的 TCPClientFrame 类和在选项卡中添加相应的组件,实现了 TCP Client 的界面设计和与服务器的连接、发送和接收消息的功能。文章来源地址https://www.toymoban.com/news/detail-500960.html

到了这里,关于python:并发编程(二十四)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【跟小嘉学 Rust 编程】二十四、内联汇编(inline assembly)

    【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学 Rust 编程】六、枚举

    2024年02月10日
    浏览(53)
  • CENTOS上的网络安全工具(二十四)Windows下的Hadoop+Spark编程环境构建

            前面我们搭建了hadoop集群,spark集群,也利用容器构建了spark的编程环境。但是一般来说,就并行计算程序的开发,一刚开始一般是在单机上的,比如hadoop的single node。但是老师弄个容器或虚拟机用vscode远程访问式开发,终究还是有些不爽。还好,hadoop和spark都是支持

    2024年02月09日
    浏览(67)
  • Python入门(二十四)异常(一)

    Python使用称为异常的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继续运行;如果未对异常进行处理,程序将停止并显示traceback,其中包含有关异常的报告。 异常是使用tr

    2024年02月09日
    浏览(39)
  • 【Python】【进阶篇】二十四、Python爬虫的Selenium的基本用法

    Selenium 作为一款 Web 自动化测试框架,提供了诸多操作浏览器的方法,本节对其中的常用方法做详细介绍。 Selenium 提供了 8 种定位单个节点的方法,如下所示: 定位节点方法 方法 | 说明 ---|--- find_element_by_id() | 通过 id 属性值定位 find_element_by_name() | 通过 name 属性值定位 find

    2024年02月04日
    浏览(88)
  • Python与CAD系列高级篇(二十四)分类提取坐标到excel

    本篇介绍以下功能开发: 1.对点、直线、多段线、圆、样条曲线分类读取坐标;2.提取坐标到excel。 需求: ① 用户选择内容。 ② 对选定内容分类提取坐标。 ③ 提取坐标到excel。 代码实现:

    2024年01月16日
    浏览(43)
  • Python遥感图像处理应用篇(二十四):Python绘制遥感图像各波段热力图(相关系数矩阵)

    给多光谱遥感图像各个波段绘制热力图,首先需要计算波段之间的相关系数矩阵,而计算遥感图像波段相关系数矩阵有不同的方法,常用的我们可以采用遥感图像处理软件计算,比如ENVI软件就可以计算相关系数矩阵,使用工具箱中的Statistics工具即可进行多种统计运算。 我们

    2023年04月09日
    浏览(51)
  • 半路出家自学当程序员这一年的经历,大家一起共勉

    2022年3月7日,我来到了上海。那是一个寒冷的夜晚。虽然因为提前找到了工作,心里还是比较踏实的。当时是我的牛马兄弟来接的我,然后我们住在了一起。这才使得我当时月薪4,000的人能够在上海得以生存。 来到上海没多久就出现了疫情,当时真的挺惨的。基本上一直是被

    2023年04月18日
    浏览(56)
  • 如何把aac转化为mp3?大家和我一起往下学习

        如何把aac转化为mp3?aac是一种先进的音频编码格式,通过较小的文件大小提供出色的音质体验。然而,由于其相对较少的普及度,与MP3相比,兼容性稍显不足,有些播放器可能无法直接识别aac格式。在某种程度上,我们可以将aac格式称为一种小众格式。考虑到这一点,一

    2024年02月11日
    浏览(36)
  • Scala第二十章节(Akka并发编程框架、Akka入门案例、Akka定时任务代码实现、两个进程间通信的案例以及简易版spark通信框架案例)

    章节目标 理解Akka并发编程框架简介 掌握Akka入门案例 掌握Akka定时任务代码实现 掌握两个进程间通信的案例 掌握简易版spark通信框架案例 1. Akka并发编程框架简介 1.1 Akka概述 Akka是一个用于构建高并发、分布式和可扩展的基于事件驱动的应用工具包。Akka是使用scala开发的库,

    2024年04月11日
    浏览(45)
  • YOLOv5系列(二十八) 本文(2万字) | 可视化工具 | Comet | ClearML | Wandb | Visdom |

    点击进入专栏: 《人工智能专栏》 Python与Python | 机器学习 | 深度学习 | 目标检测 | YOLOv5及其改进 | YOLOv8及其改进 | 关键知识点 | 各种工具教程

    2024年02月03日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包