20252307 实验三 《Python程序设计》 实验报告
学号 2025-2026-2 《Python程序设计》实验三报告
课程:《Python程序设计》
班级: 2523
姓名: 万书林
学号:20252307
实验教师:王志强
实验日期:2026年4月27日
必修/选修: 公选课
1.实验内容
(1)使用 Python 语言基于 TCP Socket 实现服务端与客户端网络通信程序
(2)实现明文输入→加密传输→接收解密功能,收发双方同时显示明文与密文(使用凯撒密码实现简单加密)
(3)加入文件操作,可保存聊天记录到文件
(5)使用 LLM 生成图形界面(GUI)版本,实现可视化加密聊天
(6)在 Windows 物理机上完成服务端与客户端通信,并与队友(学号:20252435,姓名:赵振为(其服务端ip为192.168.43.35))互相通信
(7)将所有代码托管至码云平台
2. 实验过程及结果
(1)程序设计源代码:
import socket
def caesar_encrypt_decrypt(text: str, shift: int) -> str:
result = []
for char in text:
if 32 <= ord(char) <= 126:
new_code = ord(char) + shift
if new_code > 126:
new_code -= 95
elif new_code < 32:
new_code += 95
result.append(chr(new_code))
return ''.join(result)
SHIFT = 3
创建TCP Socket对象(买手机)
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
HOST="0.0.0.0"#代表本机
PORT=8888
server.bind((HOST,PORT))#绑定(插卡)
server.listen(1)
print("服务器已经启动,等待客户端连接……")
conn,addr=server.accept()
print(f"已连接客户端:{addr}")
添加文件操作 - 打开记录文件
with open("record.txt", "a", encoding="utf-8") as f:
f.write(f"=== 聊天开始 - 客户端 {addr} 连接 ===\n")
while 1:
接收消息
data=conn.recv(1024).decode("utf-8")
if not data or data =="exit":
print("聊天结束")
# 记录聊天结束
with open("record.txt", "a", encoding="utf-8") as f:
f.write("=== 聊天结束 ===\n\n")
break
plain_data = caesar_encrypt_decrypt(data, -SHIFT)
print(f"密文:{data}")
print(f"明文:{plain_data}")
# 记录接收到的消息
with open("record.txt", "a", encoding="utf-8") as f:
f.write(f"[客户端] {plain_data}\n")
send_msg=input("我:")
encrypted_send = caesar_encrypt_decrypt(send_msg, SHIFT)
print(f"明文:{send_msg}")
print(f"密文:{encrypted_send}")
conn.send(encrypted_send.encode("utf-8"))
# 记录发送的消息
with open("record.txt", "a", encoding="utf-8") as f:
f.write(f"[服务端] {send_msg}\n")
if send_msg=="exit":
# 记录服务端主动结束聊天
with open("record.txt", "a", encoding="utf-8") as f:
f.write("=== 服务端结束聊天 ===\n\n")
break
conn.close()
server.close()
import socket
import datetime
def caesar_encrypt_decrypt(text: str, shift: int) -> str:
result = []
for char in text:
if 32 <= ord(char) <= 126:
new_code = ord(char) + shift
if new_code > 126:
new_code -= 95
elif new_code < 32:
new_code += 95
result.append(chr(new_code))
return ''.join(result)
SHIFT = 3
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = "192.168.43.35"
PORT = 8888
client.connect((HOST, PORT))
print("已连接服务端!输入exit退出聊天!")
添加文件操作 - 打开记录文件(追加模式)
with open("record.txt", "a", encoding="utf-8") as f:
f.write(f"=== 聊天开始 - 连接服务端 {HOST}:{PORT} ===\n")
while True:
#发送数据
send_msg=input("我:")
encrypted_send = caesar_encrypt_decrypt(send_msg, SHIFT)
print(f"明文:{send_msg}")
print(f"密文:{encrypted_send}")
client.send(encrypted_send.encode("utf-8"))
# 记录发送的消息
with open("record.txt", "a", encoding="utf-8") as f:
f.write(f"[客户端] {send_msg}\n")
if send_msg=="exit":
# 记录客户端主动结束聊天
with open("record.txt", "a", encoding="utf-8") as f:
f.write("=== 客户端结束聊天 ===\n\n")
break
#接收数据
data=client.recv(1024).decode("utf-8")
if not data or data=="exit":
print("聊天结束")
# 记录聊天结束
with open("record.txt", "a", encoding="utf-8") as f:
f.write("=== 聊天结束 ===\n\n")
break
plain_data = caesar_encrypt_decrypt(data, -SHIFT)
print(f"\n密文:{data}")
print(f"明文:{plain_data}")
# 记录接收到的消息
with open("record.txt", "a", encoding="utf-8") as f:
f.write(f"[服务端] {plain_data}\n")
client.close()
(2)实验结果:(与20252435赵振为合作)
我作为服务端:

通信成功,加密成功
我作为客户端:

通信成功,加密成功
(3)利用LLM完成的GUI版本
源代码:import tkinter as tk
from tkinter import scrolledtext, messagebox
import socket
import threading
def caesar_encrypt_decrypt(text: str, shift: int) -> str:
"""凯撒加密解密函数"""
result = []
for char in text:
if 32 <= ord(char) <= 126:
new_code = ord(char) + shift
if new_code > 126:
new_code -= 95
elif new_code < 32:
new_code += 95
result.append(chr(new_code))
else:
result.append(char)
return ''.join(result)
class ChatGUI:
def init(self):
self.SHIFT = 3
self.client_socket = None
self.is_server = False
self.running = True
# 创建主窗口
self.root = tk.Tk()
self.root.title("安全聊天程序 - 图形界面版")
self.root.geometry("600x500")
self.root.configure(bg='#f0f0f0')
self.setup_gui()
def setup_gui(self):
"""设置图形界面"""
# 连接设置框架
connection_frame = tk.Frame(self.root, bg='#e0e0e0', pady=10)
connection_frame.pack(fill=tk.X, padx=10, pady=5)
tk.Label(connection_frame, text="选择角色:", bg='#e0e0e0').grid(row=0, column=0, padx=5)
self.role_var = tk.StringVar(value="client")
tk.Radiobutton(connection_frame, text="客户端", variable=self.role_var,
value="client", bg='#e0e0e0').grid(row=0, column=1, padx=5)
tk.Radiobutton(connection_frame, text="服务端", variable=self.role_var,
value="server", bg='#e0e0e0').grid(row=0, column=2, padx=5)
tk.Label(connection_frame, text="IP地址:", bg='#e0e0e0').grid(row=1, column=0, padx=5, pady=5)
self.ip_entry = tk.Entry(connection_frame, width=15)
self.ip_entry.insert(0, "127.0.0.1")
self.ip_entry.grid(row=1, column=1, padx=5, pady=5)
tk.Label(connection_frame, text="端口:", bg='#e0e0e0').grid(row=1, column=2, padx=5)
self.port_entry = tk.Entry(connection_frame, width=10)
self.port_entry.insert(0, "8888")
self.port_entry.grid(row=1, column=3, padx=5)
self.connect_btn = tk.Button(connection_frame, text="连接", command=self.toggle_connection,
bg='#4CAF50', fg='white', font=('Arial', 10, 'bold'))
self.connect_btn.grid(row=1, column=4, padx=10)
# 聊天显示区域
chat_frame = tk.Frame(self.root, bg='white')
chat_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
self.chat_display = scrolledtext.ScrolledText(chat_frame, height=20, width=70,
state='disabled', bg='#fafafa')
self.chat_display.pack(fill=tk.BOTH, expand=True)
# 消息输入区域
input_frame = tk.Frame(self.root, bg='#f0f0f0')
input_frame.pack(fill=tk.X, padx=10, pady=5)
tk.Label(input_frame, text="输入消息:", bg='#f0f0f0').pack(side=tk.LEFT)
self.message_entry = tk.Entry(input_frame, width=50)
self.message_entry.pack(side=tk.LEFT, padx=5)
self.message_entry.bind('<Return>', lambda event: self.send_message())
self.send_btn = tk.Button(input_frame, text="发送", command=self.send_message,
bg='#2196F3', fg='white', state='disabled')
self.send_btn.pack(side=tk.LEFT, padx=5)
# 状态栏
self.status_var = tk.StringVar(value="准备就绪")
status_bar = tk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN,
anchor=tk.W, bg='#e0e0e0')
status_bar.pack(fill=tk.X, side=tk.BOTTOM)
def toggle_connection(self):
"""切换连接状态"""
if self.connect_btn['text'] == "连接":
self.start_connection()
else:
self.disconnect()
def start_connection(self):
"""开始连接"""
try:
port = int(self.port_entry.get())
ip = self.ip_entry.get()
if self.role_var.get() == "server":
self.start_server(ip, port)
else:
self.connect_to_server(ip, port)
except ValueError:
messagebox.showerror("错误", "端口号必须是数字!")
except Exception as e:
messagebox.showerror("错误", f"连接失败: {str(e)}")
def start_server(self, host, port):
"""启动服务端"""
def server_thread():
try:
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind((host, port))
self.server_socket.listen(1)
self.root.after(0, lambda: self.update_status(f"服务端已启动,等待客户端连接..."))
self.client_socket, addr = self.server_socket.accept()
self.is_server = True
self.running = True
self.root.after(0, lambda: self.connection_established(f"客户端 {addr} 已连接"))
self.receive_messages()
except Exception as e:
self.root.after(0, lambda: messagebox.showerror("错误", f"服务器错误: {str(e)}"))
threading.Thread(target=server_thread, daemon=True).start()
self.connect_btn.config(text="断开", bg='#f44336')
self.ip_entry.config(state='disabled')
self.port_entry.config(state='disabled')
def connect_to_server(self, host, port):
"""连接服务端"""
try:
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client_socket.connect((host, port))
self.is_server = False
self.running = True
self.connection_established(f"已连接到服务端 {host}:{port}")
threading.Thread(target=self.receive_messages, daemon=True).start()
self.connect_btn.config(text="断开", bg='#f44336')
self.ip_entry.config(state='disabled')
self.port_entry.config(state='disabled')
except Exception as e:
messagebox.showerror("错误", f"连接失败: {str(e)}")
def connection_established(self, message):
"""连接建立后的处理"""
self.send_btn.config(state='normal')
self.message_entry.config(state='normal')
self.update_status(message)
self.display_message("系统", f"{message},开始聊天吧!", "system")
def disconnect(self):
"""断开连接"""
self.running = False
if self.client_socket:
try:
self.client_socket.close()
except:
pass
if hasattr(self, 'server_socket'):
try:
self.server_socket.close()
except:
pass
self.connect_btn.config(text="连接", bg='#4CAF50')
self.send_btn.config(state='disabled')
self.ip_entry.config(state='normal')
self.port_entry.config(state='normal')
self.update_status("已断开连接")
self.display_message("系统", "连接已断开", "system")
def send_message(self):
"""发送消息"""
message = self.message_entry.get().strip()
if not message:
return
if message.lower() == 'exit':
self.disconnect()
return
try:
encrypted_msg = caesar_encrypt_decrypt(message, self.SHIFT)
self.client_socket.send(encrypted_msg.encode('utf-8'))
self.display_message("我", message, "sent")
self.message_entry.delete(0, tk.END)
except Exception as e:
messagebox.showerror("错误", f"发送失败: {str(e)}")
def receive_messages(self):
"""接收消息的线程函数"""
while self.running:
try:
data = self.client_socket.recv(1024).decode('utf-8')
if not data:
break
if data.lower() == 'exit':
self.root.after(0, self.disconnect)
break
plain_data = caesar_encrypt_decrypt(data, -self.SHIFT)
sender = "服务端" if self.is_server else "客户端"
self.root.after(0, lambda: self.display_message(sender, plain_data, "received"))
except:
if self.running:
self.root.after(0, self.disconnect)
break
def display_message(self, sender, message, msg_type):
"""在聊天区域显示消息"""
self.chat_display.config(state='normal')
# 设置不同消息类型的颜色
if msg_type == "sent":
tag = "sent"
prefix = "我: "
color = "#0066cc"
elif msg_type == "received":
tag = "received"
prefix = f"{sender}: "
color = "#cc6600"
else:
tag = "system"
prefix = "系统: "
color = "#666666"
# 配置标签样式
self.chat_display.tag_config(tag, foreground=color)
# 插入消息
self.chat_display.insert(tk.END, prefix + message + "\n", tag)
self.chat_display.config(state='disabled')
self.chat_display.see(tk.END)
def update_status(self, message):
"""更新状态栏"""
self.status_var.set(message)
def run(self):
"""运行程序"""
self.root.mainloop()
if name == "main":
app = ChatGUI()
app.run()
运行效果:

实现了图形化,但是个人认为图形化界面有些老套,不够美观
3. 实验过程中遇到的问题和解决过程
- 问题1:与队友联机时,多次失败
- 问题1解决方案:调试网络,用一方笔记本的热点互联,最后成功
其他(感悟、思考等)
socket技术为我们的通信做出了巨大贡献,我们现在使用的微信,QQ等软件都是这样技术的结果
AI生成代码能力很强,编写的GUI效果好,速度快
浙公网安备 33010602011771号