20254103 实验三《Python程序设计》实验报告

20254103 2025-2026-2 《Python程序设计》实验3报告

课程:《Python程序设计》
班级: 2541
姓名: 尉瀚文
学号:20254103
实验教师:王志强
实验日期:2026年4月28日
必修/选修: 专选课

1.实验内容

创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。

要求1:

(1)创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;

(2)要求发送方输入内容,并传输;接收方收到信息并显示。

(3)发送的信息,可以加密再传输,接收方收到后需要解密再显示(可选)。

要求2:使用LLM生成一个带图形界面的程序

(1)分析关键代码的功能和使用方法

(2)分析生成程序的优点

(3)给出运行过程和结果截图

2. 实验过程及结果

实验要求一

(1)构建服务器端/客户端。先导入socket函数并创建套接字。

image

(2)编写程序使客户端可以通过输入服务器的IP地址和端口与服务器完成对接。设置服务器和地址,IP地址为服务器所在电脑的IPV4地址。

image

 (3)进行代码构建,使服务器程序可以接受客户端的链接,并提示“接受来自 的链接”。

image

 (4)用“while”语句构建循环体系,使服务器能够不断地接受客户端的连接请求,并且根据客户端的需求做出不同的回应。通过while循环语句可以实现两端的互联交流。

image

 (5)编写“close”程序,输入“关闭服务器”,结束连接。

image

 (6)在服务端中,需要首先创建Socket对象来进行反应。然后与客户端确定同一个局域网,并且输入端口号以连接到客户端。随后开始监听连接,进入循接受客户端的连接请求。接收传来的数据,并发送给对方数据。在传输完毕后,关闭套接字。

7b8449bfb766e74961eda25af9ddbe86

 (7)在客户端中,同样也需要首先创建Socket对象,随后连接到服务器。同时注意局域网、端口号要与服务端的相同,以此建立唯一标识的网络通信端点。与服务端成功建立连接后,向其发送文字数据并等待回应。在传输完毕后,关闭套接字。

f1aed25a031f9a2f5be9a6cfda926dcd

 

实验要求二

(1)生成服务端和客户端代码,输入PyCharm。以下是LLM生成的代码

import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, messagebox, simpledialog
from datetime import datetime


class ClientGUI:
    def __init__(self):
        self.client_socket = None
        self.connected = False

        # 连接参数
        self.server_host = '172.20.10.10'
        self.server_port = 8888

        # 创建主窗口
        self.window = tk.Tk()
        self.window.title("TCP客户端")
        self.window.geometry("550x450")

        self.create_widgets()

    def create_widgets(self):
        """创建GUI组件"""
        # 连接设置框架
        self.conn_frame = tk.LabelFrame(self.window, text="连接设置", padx=5, pady=5)
        self.conn_frame.pack(fill=tk.X, padx=5, pady=5)

        tk.Label(self.conn_frame, text="服务器IP:").grid(row=0, column=0, sticky=tk.W)
        self.host_entry = tk.Entry(self.conn_frame, width=15)
        self.host_entry.insert(0, "172.20.10.10")
        self.host_entry.grid(row=0, column=1, padx=5)

        tk.Label(self.conn_frame, text="端口:").grid(row=0, column=2, sticky=tk.W)
        self.port_entry = tk.Entry(self.conn_frame, width=6)
        self.port_entry.insert(0, "8888")
        self.port_entry.grid(row=0, column=3, padx=5)

        self.connect_btn = tk.Button(self.conn_frame, text="连接服务器",
                                     command=self.connect_server, bg="blue", fg="white")
        self.connect_btn.grid(row=0, column=4, padx=5)

        self.disconnect_btn = tk.Button(self.conn_frame, text="断开连接",
                                        command=self.disconnect_server,
                                        bg="red", fg="white", state=tk.DISABLED)
        self.disconnect_btn.grid(row=0, column=5, padx=5)

        # 状态显示
        self.status_frame = tk.Frame(self.window)
        self.status_frame.pack(fill=tk.X, padx=5, pady=5)

        self.status_label = tk.Label(self.status_frame, text="未连接",
                                     fg="red", font=("Arial", 10))
        self.status_label.pack(side=tk.LEFT)

        # 消息显示区域
        self.msg_frame = tk.LabelFrame(self.window, text="聊天记录", padx=5, pady=5)
        self.msg_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        self.msg_area = scrolledtext.ScrolledText(self.msg_frame, height=20,
                                                  width=65, font=("Consolas", 10))
        self.msg_area.pack(fill=tk.BOTH, expand=True)

        # 消息输入区域
        self.send_frame = tk.Frame(self.window)
        self.send_frame.pack(fill=tk.X, padx=5, pady=5)

        self.msg_entry = tk.Entry(self.send_frame, font=("Arial", 10))
        self.msg_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
        self.msg_entry.bind('<Return>', lambda e: self.send_message())
        self.msg_entry.config(state=tk.DISABLED)

        self.send_btn = tk.Button(self.send_frame, text="发送消息",
                                  command=self.send_message, state=tk.DISABLED)
        self.send_btn.pack(side=tk.RIGHT)

    def log_message(self, message, msg_type="INFO"):
        """记录消息到聊天区域"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        color_tags = {"INFO": "black", "ERROR": "red", "SUCCESS": "green",
                      "RECEIVED": "blue", "SENT": "purple"}

        self.msg_area.insert(tk.END, f"[{timestamp}] ", "timestamp")
        self.msg_area.insert(tk.END, f"[{msg_type}] ", msg_type)
        self.msg_area.insert(tk.END, f"{message}\n", color_tags.get(msg_type, "black"))
        self.msg_area.see(tk.END)

        # 配置文本颜色
        self.msg_area.tag_config("timestamp", foreground="gray")
        self.msg_area.tag_config("INFO", foreground="black")
        self.msg_area.tag_config("ERROR", foreground="red")
        self.msg_area.tag_config("SUCCESS", foreground="green")
        self.msg_area.tag_config("RECEIVED", foreground="blue")
        self.msg_area.tag_config("SENT", foreground="purple")

    def connect_server(self):
        """连接到服务器"""
        try:
            self.server_host = self.host_entry.get()
            self.server_port = int(self.port_entry.get())

            self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.client_socket.connect((self.server_host, self.server_port))
            self.connected = True

            # 启动接收消息的线程
            self.receive_thread = threading.Thread(target=self.receive_messages, daemon=True)
            self.receive_thread.start()

            self.connect_btn.config(state=tk.DISABLED)
            self.disconnect_btn.config(state=tk.NORMAL)
            self.send_btn.config(state=tk.NORMAL)
            self.msg_entry.config(state=tk.NORMAL)
            self.status_label.config(text="已连接", fg="green")

            self.log_message(f"成功连接到服务器 {self.server_host}:{self.server_port}",
                             "SUCCESS")

        except Exception as e:
            self.log_message(f"连接服务器失败: {e}", "ERROR")
            messagebox.showerror("错误", f"无法连接到服务器: {e}")

    def receive_messages(self):
        """接收服务器消息的线程"""
        try:
            while self.connected:
                data = self.client_socket.recv(1024)
                if not data:
                    break

                message = data.decode('utf-8')
                self.log_message(message, "RECEIVED")

        except Exception as e:
            if self.connected:
                self.log_message(f"接收消息错误: {e}", "ERROR")
        finally:
            self.disconnect_server()

    def send_message(self):
        """发送消息到服务器"""
        message = self.msg_entry.get().strip()
        if message and self.connected:
            try:
                self.client_socket.send(message.encode('utf-8'))
                self.log_message(message, "SENT")
                self.msg_entry.delete(0, tk.END)
            except Exception as e:
                self.log_message(f"发送消息失败: {e}", "ERROR")
                self.disconnect_server()
        elif not self.connected:
            self.log_message("未连接到服务器,无法发送消息", "ERROR")

    def disconnect_server(self):
        """断开服务器连接"""
        if self.connected:
            self.connected = False
            if self.client_socket:
                try:
                    self.client_socket.close()
                except:
                    pass
                self.client_socket = None

            self.connect_btn.config(state=tk.NORMAL)
            self.disconnect_btn.config(state=tk.DISABLED)
            self.send_btn.config(state=tk.DISABLED)
            self.msg_entry.config(state=tk.DISABLED)
            self.status_label.config(text="未连接", fg="red")

            self.log_message("已断开与服务器的连接", "INFO")

    def on_closing(self):
        """关闭窗口时的清理"""
        self.disconnect_server()
        self.window.destroy()

    def run(self):
        """运行客户端主循环"""
        self.window.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.window.mainloop()


if __name__ == "__main__":
    client = ClientGUI()
    client.run()

(2)调试后连接成功,运行通话结果如下图所示:

f9367520c1afced1b4d8e7b31e1f5e64

 

e8815fee688aa2f8fc2da4b5b205971a

 (3)分析LLM生成代码的优势:

a.使用Tkinter构建完整GUI,状态、消息记录与发送区域分离,操作直观,界面友好。
b.加入了表情包与符号,使得通话界面更加友好,提高了通话过程的趣味性。
c. 消息分类显示与时间戳清晰,按类型着色,便于追踪。
d.涵盖了丰富的异常处理代码,能应对各种异常情况,保障代码得以良好运行。

3. 实验过程中遇到的问题和解决过程

问题1:连接过程中,个人电脑作为服务器时无法与客户端电脑相连。
解决方案1: 全面检查IP地址、端口正确性等;同时通过询问老师和同学后,关闭电脑防火墙,打开该程序的防火墙权限,即可通信,进而解决问题。

问题2:输入正确IP地址后发现仍无法链接
解决方案2:是端口的问题,客户端应与服务端输入一样的端口;以及IP地址应该输入同一个。

其他(感悟、思考等)

       在Python的学习中要持续跟进老师的讲解,尤其是要注意老师在课堂上讲授的易错易混的点,这在我们具体的实验操作中是极其重要的;其次是要对之前教的知识点进行回顾,不然在后期的编写中会屡次犯错;最后要注意细节,在具体操作中要时刻关注缩进和函数等小问题,不然最后检查整体程序时会十分麻烦,错误不易发现。然而,目前我自身仍存在对Python程序中基本模块运用与编写规则语法不熟悉的问题,遇到的阻力较大,还需要进一步熟悉模块使用和基本语法。此外,该程序需要两台电脑的IP地址、端口、代码都正确无误才可以正常运行,这要求我们必须仔细核对所有信息,这个过程也有助于培养我们的细心、耐心和团队协作能力。

参考资料

posted @ 2026-04-30 20:47  尉瀚文  阅读(3)  评论(0)    收藏  举报