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

课程:《Python程序设计》
班级: 2523
姓名: 陈冠宇
学号:20252320
实验教师:王志强
实验日期:2026年5月11日
必修/选修: 公选课

1.实验内容
注意事项:

每人必须做一次客户端和一次服务端,且要和队友(标注学号姓名)互相通信。

要求1:

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

(2)要求发送方输入内容,加密后并传输;接收方收到密文并解密和显示。要求:发方和收方同时输出明文和明文。

(3)程序代码托管到码云。

(4)添加文件操作,有加分。(可选项)

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

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

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

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

(4)程序代码托管到码云。

注:在华为ECS服务器(OpenOuler系统)和物理机(Windows/Linux系统)上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

  1. 实验过程及结果
    1.作为服务端接收消息
    代码:`import socket
    def decrypt(text):
    res = ""
    for c in text:
    if c.isalpha():
    if c.islower():
    res += chr((ord(c)-ord('a')-3)%26 + ord('a'))
    else:
    res += chr((ord(c)-ord('A')-3)%26 + ord('A'))
    else:
    res += c
    return res
    HOST = '192.168.31.236'
    PORT = 8890

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
print("服务端已启动,等待你连接...")

conn, addr = s.accept()
print(f"已和你建立连接:{addr}")

cipher = conn.recv(1024).decode("utf-8")
plain = decrypt(cipher)

print(f"【服务端-密文】{cipher}")
print(f"【服务端-明文】{plain}")

conn.close()
s.close()结果 ![屏幕截图 2026-05-11 214202](https://img2024.cnblogs.com/blog/3788288/202605/3788288-20260512073455350-2010187791.png) 2.作为客户端发送消息 代码:import socket
def encrypt(text):
res = ""
for c in text:
if c.isalpha():
if c.islower():
res += chr((ord(c)-ord('a')+3)%26 + ord('a'))
else:
res += chr((ord(c)-ord('A')+3)%26 + ord('A'))
else:
res += c
return res
HOST = '192.168.31.157'
PORT = 8891

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

plain = input("请输入发给同学的消息:")
cipher = encrypt(plain)

print(f"【客户端-明文】{plain}")
print(f"【客户端-密文】{cipher}")

s.send(cipher.encode("utf-8"))
s.close()`
结果:

屏幕截图 2026-05-11 221150
GUI生成的可视界面代码
`import tkinter as tk
from tkinter import ttk, scrolledtext, filedialog, messagebox
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
import os
from datetime import datetime

class EncryptionApp:
def init(self, root):
self.root = root
self.root.title("安全加解密系统 - AES-256-CBC")
self.root.geometry("900x700")
self.root.resizable(True, True)

设置密钥(16/24/32字节对应AES-128/192/256)

self.key = b'0123456789abcdef0123456789abcdef' # 32字节,AES-256

self.create_widgets()

def create_widgets(self):
# 样式配置
style = ttk.Style()
style.theme_use('clam')

主框架

main_frame = ttk.Frame(self.root, padding="10")
main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

发送方区域

sender_frame = ttk.LabelFrame(main_frame, text="发送方(加密端)", padding="10")
sender_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)

ttk.Label(sender_frame, text="明文输入:").grid(row=0, column=0, sticky=tk.W)
self.sender_plaintext = scrolledtext.ScrolledText(sender_frame, height=8, width=50)
self.sender_plaintext.grid(row=1, column=0, columnspan=2, pady=5)

发送方按钮

btn_frame1 = ttk.Frame(sender_frame)
btn_frame1.grid(row=2, column=0, columnspan=2, pady=10)
ttk.Button(btn_frame1, text="加密并传输", command=self.encrypt_and_transmit).pack(side=tk.LEFT, padx=5)
ttk.Button(btn_frame1, text="从文件加载明文", command=self.load_plaintext_file).pack(side=tk.LEFT, padx=5)

ttk.Label(sender_frame, text="密文(Base64编码):").grid(row=3, column=0, sticky=tk.W, pady=(10, 0))
self.ciphertext_display = scrolledtext.ScrolledText(sender_frame, height=4, width=50, bg="#f0f0f0")
self.ciphertext_display.grid(row=4, column=0, columnspan=2, pady=5)

发送方输出明文

ttk.Label(sender_frame, text="发送方明文输出:").grid(row=5, column=0, sticky=tk.W, pady=(10, 0))
self.sender_output = scrolledtext.ScrolledText(sender_frame, height=4, width=50, bg="#e8f4e8")
self.sender_output.grid(row=6, column=0, columnspan=2, pady=5)

接收方区域

receiver_frame = ttk.LabelFrame(main_frame, text="接收方(解密端)", padding="10")
receiver_frame.grid(row=0, column=1, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5, padx=(10, 0))

ttk.Label(receiver_frame, text="接收到的密文:").grid(row=0, column=0, sticky=tk.W)
self.receiver_ciphertext = scrolledtext.ScrolledText(receiver_frame, height=8, width=50)
self.receiver_ciphertext.grid(row=1, column=0, columnspan=2, pady=5)

接收方按钮

btn_frame2 = ttk.Frame(receiver_frame)
btn_frame2.grid(row=2, column=0, columnspan=2, pady=10)
ttk.Button(btn_frame2, text="解密并显示", command=self.decrypt_and_display).pack(side=tk.LEFT, padx=5)
ttk.Button(btn_frame2, text="保存解密结果到文件", command=self.save_decrypted_file).pack(side=tk.LEFT, padx=5)

ttk.Label(receiver_frame, text="解密后的明文:").grid(row=3, column=0, sticky=tk.W, pady=(10, 0))
self.receiver_plaintext = scrolledtext.ScrolledText(receiver_frame, height=4, width=50, bg="#e8f4e8")
self.receiver_plaintext.grid(row=4, column=0, columnspan=2, pady=5)

接收方输出明文

ttk.Label(receiver_frame, text="接收方明文输出:").grid(row=5, column=0, sticky=tk.W, pady=(10, 0))
self.receiver_output = scrolledtext.ScrolledText(receiver_frame, height=4, width=50, bg="#e8f4e8")
self.receiver_output.grid(row=6, column=0, columnspan=2, pady=5)

日志区域

log_frame = ttk.LabelFrame(main_frame, text="操作日志", padding="10")
log_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=10)
self.log_text = scrolledtext.ScrolledText(log_frame, height=8, width=100, bg="#fef9e6")
self.log_text.grid(row=0, column=0, sticky=(tk.W, tk.E))

配置网格权重

self.root.columnconfigure(0, weight=1)
self.root.rowconfigure(0, weight=1)
main_frame.columnconfigure(0, weight=1)
main_frame.columnconfigure(1, weight=1)
log_frame.columnconfigure(0, weight=1)

def log(self, message):
"""记录日志"""
timestamp = datetime.now().strftime("%H:%M:%S")
self.log_text.insert(tk.END, f"[{timestamp}] {message}\n")
self.log_text.see(tk.END)

def encrypt_data(self, plaintext):
"""AES加密数据"""
try:
# 生成随机IV
iv = os.urandom(16)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
# 填充并加密
padded_data = pad(plaintext.encode('utf-8'), AES.block_size)
ciphertext = cipher.encrypt(padded_data)
# 组合IV和密文,并进行Base64编码
encrypted_data = base64.b64encode(iv + ciphertext).decode('utf-8')
return encrypted_data
except Exception as e:
messagebox.showerror("错误", f"读取文件失败: {str(e)}")

def save_decrypted_file(self):
"""保存解密结果到文件"""
plaintext = self.receiver_plaintext.get("1.0", tk.END).strip()
if not plaintext:
messagebox.showwarning("警告", "没有解密的明文可保存!")
return

filepath = filedialog.asksaveasfilename(
title="保存解密结果",
defaultextension=".txt",
filetypes=[("文本文件", ".txt"), ("所有文件", ".*")]
)
if filepath:
try:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(plaintext)
self.log(f"解密结果已保存到: {os.path.basename(filepath)}")
messagebox.showinfo("成功", "文件保存成功!")
except Exception as e:
messagebox.showerror("错误", f"保存文件失败: {str(e)}")

def main():
root = tk.Tk()
app = EncryptionApp(root)
root.mainloop()

if name == "main":
main()
`
结果:

  1. 实验过程中遇到的问题和解决过程
    问题1:链接服务端时提示超时,发现可能是不在同一局域网或端口不一导致
    问题1解决方案:连接到同一局域网后重新启动
    问题2:服务端无法启动,发现为没及时更改IP地址
    问题2解决方案:在命令提示符中再次查询IPV4地址并修改代码
posted @ 2026-05-12 12:38  小天冰星  阅读(19)  评论(3)    收藏  举报