当前位置: 首页 > news >正文

20252410李沐泽实验三报告

20252410 2025-2026-2《Python程序设计》

实验三报告

课程:《Python 程序设计》
班级: 2524
姓名: 李沐泽
学号:20252410
实验教师:王志强
实验日期:2026 年 4 月 27 日
必修 / 选修: 公选课
1. 实验内容
基于 Python 的Socket TCP实现服务端与客户端。
客户端从本地文件读取明文,加密后发送;服务端接收密文并解密保存。
发送方与接收方同时输出明文与密文,展示加密传输全过程。
完成文件读写、加密解密。
使用大模型生成图形界面 GUI 版程序,完成代码分析、运行测试。
程序在 Windows 物理机运行,代码托管到码云。
2. 实验过程及结果
2.1 实验环境
开发工具:PyCharm、VIM、IDLE
操作系统:Windows11、华为 ECS OpenEuler
通信协议:TCP
端口:8988
加密方式:ASCII 偏移加密
2.2 控制台版程序(满足要求 1)
2.2.1 服务端代码
屏幕截图 2026-04-27 204734

2.2.2 客户端代码
屏幕截图 2026-04-27 204843

2.2.3 运行步骤
(1)运行服务端server.py
(2)运行客户端client.py
(3)客户端输出明文 + 密文并发送
(4)服务端输出密文 + 明文并保存文件
2.2.4 运行结果示例
客户端显示
屏幕截图 2026-04-27 202016
服务端显示
image

2.3LLM生成 GUI 图形界面版(满足要求 2)
2.3.1 GUI 完整代码
(1)服务端
import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, messagebox, ttk
import queue
def decrypt(text):
"""解密:ASCII值 - 1"""
return "".join(chr(ord(char) - 1) for char in text)
class ServerGUI:
def init(self, root):
self.root = root
self.root.title("252310 网络通信服务端 (GUI版)")
self.root.geometry("620x520")
self.root.resizable(False, False)

    self.server_thread = Noneself.server_socket = Noneself.running = Falseself.log_queue = queue.Queue()self.setup_ui()self.root.after(100, self.process_log_queue)def setup_ui(self):ctrl_frame = ttk.Frame(self.root, padding=10)ctrl_frame.pack(fill=tk.X)ttk.Label(ctrl_frame, text="主机:").grid(row=0, column=0, padx=5)self.host_var = tk.StringVar(value="192.168.25.10")ttk.Entry(ctrl_frame, textvariable=self.host_var, width=15).grid(row=0, column=1, padx=5)ttk.Label(ctrl_frame, text="端口:").grid(row=0, column=2, padx=5)self.port_var = tk.StringVar(value="8988")ttk.Entry(ctrl_frame, textvariable=self.port_var, width=8).grid(row=0, column=3, padx=5)self.start_btn = ttk.Button(ctrl_frame, text="▶ 启动服务", command=self.start_server)self.start_btn.grid(row=0, column=4, padx=10)self.stop_btn = ttk.Button(ctrl_frame, text="⏹ 停止服务", command=self.stop_server, state=tk.DISABLED)self.stop_btn.grid(row=0, column=5, padx=5)ttk.Label(self.root, text="📡 运行日志 & 数据监控:", font=("Microsoft YaHei", 10, "bold")).pack(anchor=tk.W,padx=12,pady=(8, 0))self.log_area = scrolledtext.ScrolledText(self.root, height=18, state=tk.DISABLED, wrap=tk.WORD,font=("Consolas", 9))self.log_area.pack(fill=tk.BOTH, expand=True, padx=12, pady=5)self.status_var = tk.StringVar(value="就绪:等待启动")ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W, font=("Arial", 9)).pack(fill=tk.X, padx=12, pady=5)ttk.Label(self.root, text="版权所有:besti 20252328 向一", font=("Arial", 9, "italic"), foreground="gray").pack(pady=3)def log(self, msg):self.log_queue.put(msg)def process_log_queue(self):try:while True:msg = self.log_queue.get_nowait()self.log_area.config(state=tk.NORMAL)self.log_area.insert(tk.END, msg + "\n")self.log_area.see(tk.END)self.log_area.config(state=tk.DISABLED)except queue.Empty:passself.root.after(100, self.process_log_queue)def start_server(self):if self.running: returnhost = self.host_var.get()try:port = int(self.port_var.get())except ValueError:messagebox.showerror("错误", "端口号必须是整数!");returnself.start_btn.config(state=tk.DISABLED)self.stop_btn.config(state=tk.NORMAL)self.status_var.set("正在绑定端口并启动监听...")self.log("🔧 正在初始化服务器...")self.running = Trueself.server_thread = threading.Thread(target=self._server_loop, args=(host, port), daemon=True)self.server_thread.start()self.log("✅ 服务器后台线程已启动")def stop_server(self):self.running = Falseself.status_var.set("正在停止服务...")self.log("🛑 收到停止请求,正在关闭监听...")if self.server_socket:try:self.server_socket.close()except:passself.start_btn.config(state=tk.NORMAL)self.stop_btn.config(state=tk.DISABLED)def _server_loop(self, host, port):try:self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)self.server_socket.bind((host, port))self.server_socket.listen(5)self.log(f"🌐 252328服务端已启动,监听 {host}:{port}")self.status_var.set(f"🟢 运行中:{host}:{port}")while self.running:self.log("⏳ 等待客户端连接...")try:self.server_socket.settimeout(1.0)client_socket, addr = self.server_socket.accept()except socket.timeout:continueexcept OSError:breakself.log(f"📥 客户端已连接:{addr}")self.status_var.set(f"🔗 已连接:{addr}")try:data = client_socket.recv(4096).decode("utf-8")if not data:self.log("⚠️ 客户端未发送数据或已断开");continuedecrypted = decrypt(data)self.log(f"🔒 接收密文:{data}")self.log(f"🔓 解密明文:{decrypted}")with open("接收文件.txt", "w", encoding="utf-8") as f:f.write(decrypted)self.log("💾 已保存至:接收文件.txt")self.status_var.set("✅ 数据处理完成,等待下一次连接")except Exception as e:self.log(f"❌ 数据处理异常:{e}")finally:client_socket.close()self.log("🔌 客户端连接已释放")except Exception as e:self.log(f"💥 服务器启动/运行失败:{e}")finally:self.running = Falseself.status_var.set("🔴 服务已停止")if self.root.winfo_exists():self.root.after(0, lambda: self.start_btn.config(state=tk.NORMAL))self.root.after(0, lambda: self.stop_btn.config(state=tk.DISABLED))

if name == 'main':
root = tk.Tk()
app = ServerGUI(root)
root.mainloop()
(2)客户端
import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, messagebox, ttk
import queue

def encrypt(text):
"""加密:ASCII值 + 1"""
return "".join(chr(ord(char) + 1) for char in text)

class ClientGUI:
def init(self, root):
self.root = root
self.root.title("252328 网络通信客户端 (GUI版)")
self.root.geometry("560x580")
self.root.resizable(False, False)

    self.log_queue = queue.Queue()self.is_sending = Falseself.setup_ui()self.root.after(100, self.process_log_queue)def setup_ui(self):frm_cfg = ttk.LabelFrame(self.root, text="🌐 服务器配置", padding=10)frm_cfg.pack(fill=tk.X, padx=10, pady=5)ttk.Label(frm_cfg, text="IP地址:").grid(row=0, column=0, sticky=tk.W, padx=5)self.ip_var = tk.StringVar(value="192.168.25.10")ttk.Entry(frm_cfg, textvariable=self.ip_var, width=18).grid(row=0, column=1, padx=5)ttk.Label(frm_cfg, text="端口:").grid(row=0, column=2, sticky=tk.W, padx=5)self.port_var = tk.StringVar(value="8988")ttk.Entry(frm_cfg, textvariable=self.port_var, width=8).grid(row=0, column=3, padx=5)frm_in = ttk.LabelFrame(self.root, text="📝 数据输入与加密", padding=10)frm_in.pack(fill=tk.X, padx=10, pady=5)ttk.Label(frm_in, text="发送内容:").grid(row=0, column=0, sticky=tk.NW, padx=5, pady=2)self.input_txt = tk.Text(frm_in, height=3, width=45, font=("Consolas", 10))self.input_txt.grid(row=0, column=1, padx=5, pady=2, sticky=tk.W)ttk.Label(frm_in, text="加密预览:").grid(row=1, column=0, sticky=tk.NW, padx=5, pady=2)self.enc_preview = tk.Text(frm_in, height=1, width=45, state=tk.DISABLED, font=("Consolas", 10), bg="#f0f0f0")self.enc_preview.grid(row=1, column=1, padx=5, pady=2, sticky=tk.W)frm_btn = ttk.Frame(self.root)frm_btn.pack(fill=tk.X, padx=10, pady=5)ttk.Button(frm_btn, text="🔒 预览加密", command=self.preview_encrypt).pack(side=tk.LEFT, padx=5)self.send_btn = ttk.Button(frm_btn, text="📤 连接并发送", command=self.start_send)self.send_btn.pack(side=tk.LEFT, padx=5)ttk.Label(self.root, text="📡 运行日志:", font=("Microsoft YaHei", 9, "bold")).pack(anchor=tk.W, padx=12, pady=(5,0))self.log_area = scrolledtext.ScrolledText(self.root, height=15, state=tk.DISABLED, wrap=tk.WORD, font=("Consolas", 9))self.log_area.pack(fill=tk.BOTH, expand=True, padx=12, pady=5)ttk.Label(self.root, text="版权所有:besti 20252328 向一", font=("Arial", 9, "italic"), foreground="gray").pack(pady=3)def log(self, msg): self.log_queue.put(msg)def process_log_queue(self):try:while True:msg = self.log_queue.get_nowait()self.log_area.config(state=tk.NORMAL)self.log_area.insert(tk.END, msg + "\n")self.log_area.see(tk.END)self.log_area.config(state=tk.DISABLED)except queue.Empty: passself.root.after(100, self.process_log_queue)def preview_encrypt(self):content = self.input_txt.get("1.0", tk.END).strip()if not content: messagebox.showwarning("提示", "请先输入内容!"); returnenc = encrypt(content)self.enc_preview.config(state=tk.NORMAL)self.enc_preview.delete("1.0", tk.END)self.enc_preview.insert("1.0", enc)self.enc_preview.config(state=tk.DISABLED)self.log(f"🔍 原文: {content}")self.log(f"🔒 密文预览: {enc}")def start_send(self):if self.is_sending: returnself.is_sending = Trueself.send_btn.config(state=tk.DISABLED)t = threading.Thread(target=self._send_logic, daemon=True)t.start()def _send_logic(self):client_socket = Nonetry:content = self.input_txt.get("1.0", tk.END).strip()if not content: self.log("⚠️ 发送内容为空!"); returnself.log("🔒 正在加密...")enc_content = encrypt(content)self.log("💾 正在写入 发送文件.txt ...")with open("发送文件.txt", "w", encoding="utf-8") as f:f.write(enc_content)self.log("📤 正在读取文件并连接服务器...")with open("发送文件.txt", "r", encoding="utf-8") as f:send_data = f.read()server_ip = self.ip_var.get()server_port = int(self.port_var.get())client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client_socket.settimeout(5.0)client_socket.connect((server_ip, server_port))self.log(f"✅ 已连接至 {server_ip}:{server_port}")client_socket.send(send_data.encode("utf-8"))self.log("📤 加密数据发送成功!")self.root.after(0, lambda: messagebox.showinfo("成功", "文件已成功发送至服务端!"))except ConnectionRefusedError:self.log("❌ 连接失败:服务器未启动或IP/端口错误")except socket.timeout:self.log("⏱️ 连接超时:请检查网络或防火墙设置")except Exception as e:self.log(f"💥 发送异常:{e}")finally:self.is_sending = Falseself.root.after(0, lambda: self.send_btn.config(state=tk.NORMAL))if client_socket: client_socket.close()

if name == 'main':
root = tk.Tk()
app = ClientGUI(root)
root.mainloop()
2.3.2 关键代码功能
加密解密:ASCII 偏移实现简单加密。
Socket TCP:实现稳定连接、数据收发。
多线程:支持多客户端并发处理。
tkinter GUI:窗口、日志、文件选择、弹窗提示。
文件操作:读取发送文件、写入接收文件。
2.3.3 GUI 程序优点
可视化操作,无需命令行。
明文密文实时展示,直观清晰。
跨平台运行(Windows/Linux/OpenEuler)。
代码模块化,易读易维护。
支持多客户端、文件选择、状态提示,功能完整。
2.3.4 运行过程
启动 GUI 程序,选择启动服务端。
屏幕截图 2026-04-27 205527

启动客户端,选择 txt 文件,输入 IP。
点击发送文件。
服务端自动接收、解密、保存。
界面显示明文、密文与运行状态。
屏幕截图 2026-04-27 205509

3. 实验过程中遇到的问题和解决过程
问题 1:客户端连接超时或连接失败
问题 1 解决方案:手动设置子网IP地址。
问题 2:中文传输乱码
问题 2 解决方案:文件读写与 socket 编码统一使用 utf-8。

4. 其他(感悟、思考等)
通过本次实验,我掌握了 Socket TCP 通信的完整流程,理解了服务端监听、客户端请求、数据加密解密、文件传输的原理。多线程、文件操作、编码处理、服务器配置等能力得到了综合提升。
使用大模型生成 GUI 程序极大提高了开发效率,同时也锻炼了代码阅读与优化能力。本次实验将网络编程、文件处理、数据安全、图形界面结合在一起,是非常实用的 Python 实战训练。
5. 码云托管
已将以下代码上传至码云仓库:
(客户端)https://gitee.com/lmzmz/PythonProject9/blob/2e18fa108908ce2325209e128383ccf787e985bc/客户端.py
(服务端)
https://gitee.com/lmzmz/Project3/commit/e4e041882daade69c5f8838ddce4344728066f20

http://www.jsqmd.com/news/715642/

相关文章:

  • 告别复杂配置!OpCore Simplify:3步搞定黑苹果OpenCore EFI配置
  • 【Java多租户安全隔离黄金标准】:20年架构师亲授5层数据隔离防线,99.99%企业尚未启用的生产级方案
  • 千问3.5-2B实战案例:社交媒体截图→敏感内容识别+舆情倾向分析+回应话术生成
  • 限时公开!8款免费AI论文生成器,一键初稿AIGC率低至9% - 麟书学长
  • MCP插件启动即崩溃,日志却只显示“Failed to connect to MCP server”?——3步诊断法+7个隐藏配置项拯救你的开发流
  • 终极指南:如何快速批量下载MediaFire文件夹内容
  • 自动驾驶泊车全面解析
  • Florence-2视觉模型实例分割实战指南
  • 终极内存修改利器:CheatEngine-DMA插件完整指南
  • JDK8中新日期时间API
  • 版图工程师的键盘交响曲:Move/Copy/Slot之外,这些Virtuoso冷门快捷键让你的效率翻倍
  • 鸣潮自动化工具终极指南:3分钟配置,解放你的游戏时间
  • 不止于做题:用C语言实现链表花式重排,解锁数据处理新思路
  • 抖音批量下载终极指南:3步搞定无水印视频自动化处理
  • 从树莓派CM4载板迁移到地平线RDK X3模组:一份详细的引脚兼容性与避坑指南
  • 常见 HTTP 状态码详解
  • 抖音无水印下载工具:5分钟学会批量保存视频和直播内容
  • Intel多核处理器与SIMD在数字信号处理中的应用与优化
  • **WebGPU实战:从零构建高性能图形渲染引擎的创新路径**在现代Web开发中,**WebGPU**作为下一代图形和计算API
  • 期货资管系统选型指南:如何选择安全高效的 - 大宗商品交易系统开发
  • VS Code Copilot Next 智能工作流配置实战手册(2024企业级SOP已验证):覆盖CI/CD集成、多环境变量注入、GitOps联动全链路
  • Dify工作流实战指南:从零构建智能应用的7大核心场景
  • 点云配准效率翻倍:深入浅出图解Fast Global Registration的‘四元约束’到底在干嘛
  • 2026年必知!本地全自动码垛机器人定制厂家电话曝光 - GrowthUME
  • 【TB6612是否可以驱动三线无刷电机】
  • 群面智伴,前端界面
  • 别再硬调PID了!用Python+PyBullet给机械臂动力学模型做个‘体检’,让控制参数自己‘跑’出来
  • 实时视频翻译系统架构优化与工程实践
  • 告别繁琐操作:ARK: Survival Evolved 玩家的终极启动器指南
  • 2026年必看!杭州这家大号倾角皮带输送机厂为何受推荐? - GrowthUME