20243429 2025-2026-2 《Python程序设计》实验三报告
课程:《Python程序设计》
班级: 2434
姓名: 付家祺
学号:20243429
实验教师:王志强老师
实验日期:2026年4月27日
必修/选修: 公选课
一.实验内容
创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
要求1:
(1)创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;
(2)要求发送方输入内容,加密后并传输;接收方收到密文并解密和显示(需要发方和收方同时输出明文和明文);
(3)程序代码托管到码云;
(4)添加文件操作。
要求2:
使用LLM生成一个带图形界面的程序
(1)分析关键代码的功能和使用方法;
(2)分析生成程序的优点;
(3)给出运行过程和结果截图;
(4)程序代码托管到码云。
二. 实验过程及结果
实验代码:
服务端的代码如下:
点击查看代码
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = "192.168.31.29"
PORT = 4444
server.bind((HOST, PORT))
server.listen(1)
print("服务端已启动,等待客户端连接")
conn, addr = server.accept()
print("已连接客户端:", addr)
f = open("server_chat.txt", "w", encoding="utf-8")
try:
while True:
cipher = conn.recv(1024).decode("utf-8")
if not cipher:
print("聊天结束")
break
plain = ''.join([chr(ord(c) - 8) for c in cipher])
if plain == "exit":
print("聊天结束")
break
print("\n【收到】密文:" + cipher)
print("【解密】明文:" + plain)
f.write("【收到】密文:" + cipher + "\n")
f.write("【解密】明文:" + plain + "\n")
send_plain = input("我:")
send_cipher = ''.join([chr(ord(c) + 8) for c in send_plain])
conn.send(send_cipher.encode("utf-8"))
if send_plain == "exit":
print("聊天结束")
break
print("【发送】明文:" + send_plain)
print("【发送】密文:" + send_cipher + "\n")
f.write("【发送】明文:" + send_plain + "\n")
f.write("【发送】密文:" + send_cipher + "\n\n")
finally:
f.close()
conn.close()
server.close()
print("进程已结束,退出代码为 0")
服务端代码分析
创建 TCP socket,绑定到 192.168.31.29:4444 并开始监听。
等待客户端连接,连接成功后获取客户端连接对象与地址。
打开 server_chat.txt 文件用于记录聊天日志。
进入循环:接收客户端发来的密文,若为空则结束聊天。
对密文进行解密(每个字符 ASCII 码减 8)。
若解密后明文为 exit,结束聊天。打印收到的密文与解密后的明文,并写入文件。用户输入回复消息(明文)。
加密后发送给客户端,同时打印明文和密文并记录到文件。
若发送 exit,跳出循环关闭连接。
循环结束后关闭文件、客户端连接与服务端 socket。
客户端的代码如下:
点击查看代码
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = "192.168.31.10"
PORT = 4444
client.connect((HOST, PORT))
print("已连接服务端!输入exit退出聊天!")
f = open("client_chat.txt", "w", encoding="utf-8")
try:
while True:
send_plain = input("我:")
send_cipher = ''.join([chr(ord(c) + 8) for c in send_plain])
client.send(send_cipher.encode("utf-8"))
if send_plain == "exit":
print("聊天结束")
break
print("【发送】明文:" + send_plain)
print("【发送】密文:" + send_cipher + "\n")
f.write("【发送】明文:" + send_plain + "\n")
f.write("【发送】密文:" + send_cipher + "\n\n")
cipher = client.recv(1024).decode("utf-8")
if not cipher:
print("聊天结束")
break
plain = ''.join([chr(ord(c) - 8) for c in cipher])
if plain == "exit":
print("聊天结束")
break
print("【收到】密文:" + cipher)
print("【解密】明文:" + plain + "\n")
f.write("【收到】密文:" + cipher + "\n")
f.write("【解密】明文:" + plain + "\n\n")
finally:
f.close()
client.close()
print("进程已结束,退出代码为 0")
客户端代码分析:
创建 TCP socket,连接到 192.168.31.10:4444。
连接成功后,打开 client_chat.txt 文件记录聊天日志。
进入循环:用户输入消息(明文)。加密后发送给服务端,同时打印明文和密文并写入文件。
若发送 exit,跳出循环关闭连接。
否则,接收服务端回复的密文,若为空则结束聊天。
对密文解密,若明文为 exit 则结束聊天。
打印收到的密文与解密后的明文,并写入文件。
循环结束后关闭文件与客户端 socket。
实验结果如下:
启动服务端时,密文(采用凯撒密码,利用ASCII+8)和明文一同显示:

启动客户端时,密文(采用凯撒密码,利用ASCII+8)和明文一同显示:

将服务端与客户端的传输记录添加至文件中:


利用LLM生成一个带图形界面的程序:
服务端代码如下:
点击查看代码
import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, messagebox
# 加密解密函数
def encrypt(text):
return ''.join([chr(ord(c) + 8) for c in text])
def decrypt(text):
return ''.join([chr(ord(c) - 8) for c in text])
class ServerGUI:
def __init__(self, root):
self.root = root
self.root.title("TCP 加密聊天 - 服务端")
self.root.geometry("650x550")
# IP 和端口
self.HOST = "172.16.221.47" # 监听所有网卡
self.PORT = 4444
# 组件
tk.Label(root, text="聊天记录(明文+密文)", font=("微软雅黑", 12)).pack(pady=5)
self.chat_area = scrolledtext.ScrolledText(root, width=75, height=25, state=tk.DISABLED)
self.chat_area.pack(pady=5)
self.entry_msg = tk.Entry(root, width=50, font=("微软雅黑", 12))
self.entry_msg.pack(pady=5)
self.entry_msg.bind("<Return>", self.send_msg)
tk.Button(root, text="发送", command=self.send_msg, width=10).pack()
# 套接字
self.server_socket = None
self.client_conn = None
self.f = None
# 启动服务端线程
threading.Thread(target=self.start_server, daemon=True).start()
def start_server(self):
try:
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind((self.HOST, self.PORT))
self.server_socket.listen(5)
self.show_msg(f"服务端已启动,端口:{self.PORT}\n等待客户端连接...")
# 打开记录文件
self.f = open("server_chat_gui.txt", "w", encoding="utf-8")
# 等待客户端连接
self.client_conn, addr = self.server_socket.accept()
self.show_msg(f"客户端已连接:{addr}\n")
# 接收消息循环
while True:
cipher = self.client_conn.recv(1024).decode("utf-8")
if not cipher:
break
plain = decrypt(cipher)
if plain == "exit":
self.show_msg("\n【对方退出聊天】")
break
self.show_msg(f"\n【收到】密文:{cipher}")
self.show_msg(f"【解密】明文:{plain}")
self.save_log(f"【收到】密文:{cipher}\n【解密】明文:{plain}\n")
except Exception as e:
messagebox.showerror("错误", str(e))
def send_msg(self, event=None):
if not self.client_conn:
messagebox.showwarning("提示", "未连接客户端")
return
plain = self.entry_msg.get().strip()
if not plain:
return
cipher = encrypt(plain)
self.client_conn.send(cipher.encode("utf-8"))
self.show_msg(f"\n【发送】明文:{plain}")
self.show_msg(f"【发送】密文:{cipher}")
self.save_log(f"【发送】明文:{plain}\n【发送】密文:{cipher}\n\n")
self.entry_msg.delete(0, tk.END)
if plain == "exit":
self.client_conn.close()
self.server_socket.close()
self.root.quit()
def show_msg(self, msg):
self.chat_area.config(state=tk.NORMAL)
self.chat_area.insert(tk.END, msg + "\n")
self.chat_area.config(state=tk.DISABLED)
self.chat_area.see(tk.END)
def save_log(self, text):
if self.f:
self.f.write(text)
self.f.flush()
if __name__ == "__main__":
root = tk.Tk()
app = ServerGUI(root)
root.mainloop()
LLM客户端代码如下:
点击查看代码
import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, messagebox
# 加密解密
def encrypt(text):
return ''.join([chr(ord(c) + 8) for c in text])
def decrypt(text):
return ''.join([chr(ord(c) - 8) for c in text])
class ClientGUI:
def __init__(self, root):
self.root = root
self.root.title("TCP 加密聊天 - 客户端")
self.root.geometry("650x550")
# 服务端IP(改成你自己的服务端IP)
self.HOST = "127.0.0.1"
self.PORT = 4444
# 界面
tk.Label(root, text="聊天记录(明文+密文)", font=("微软雅黑", 12)).pack(pady=5)
self.chat_area = scrolledtext.ScrolledText(root, width=75, height=25, state=tk.DISABLED)
self.chat_area.pack(pady=5)
self.entry_msg = tk.Entry(root, width=50, font=("微软雅黑", 12))
self.entry_msg.pack(pady=5)
self.entry_msg.bind("<Return>", self.send_msg)
tk.Button(root, text="发送", command=self.send_msg, width=10).pack()
# 套接字
self.client_socket = None
self.f = None
# 连接服务端
threading.Thread(target=self.connect_server, daemon=True).start()
def connect_server(self):
try:
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client_socket.connect((self.HOST, self.PORT))
self.show_msg("已成功连接服务端!\n")
self.f = open("client_chat_gui.txt", "w", encoding="utf-8")
# 接收消息
while True:
cipher = self.client_socket.recv(1024).decode("utf-8")
if not cipher:
break
plain = decrypt(cipher)
if plain == "exit":
self.show_msg("\n【对方退出聊天】")
break
self.show_msg(f"\n【收到】密文:{cipher}")
self.show_msg(f"【解密】明文:{plain}")
self.save_log(f"【收到】密文:{cipher}\n【解密】明文:{plain}\n")
except Exception as e:
messagebox.showerror("连接失败", "请检查服务端是否启动")
print(e)
def send_msg(self, event=None):
if not self.client_socket:
messagebox.showwarning("提示", "未连接服务端")
return
plain = self.entry_msg.get().strip()
if not plain:
return
cipher = encrypt(plain)
self.client_socket.send(cipher.encode("utf-8"))
self.show_msg(f"\n【发送】明文:{plain}")
self.show_msg(f"【发送】密文:{cipher}")
self.save_log(f"【发送】明文:{plain}\n【发送】密文:{cipher}\n\n")
self.entry_msg.delete(0, tk.END)
if plain == "exit":
self.client_socket.close()
self.root.quit()
def show_msg(self, msg):
self.chat_area.config(state=tk.NORMAL)
self.chat_area.insert(tk.END, msg + "\n")
self.chat_area.config(state=tk.DISABLED)
self.chat_area.see(tk.END)
def save_log(self, text):
if self.f:
self.f.write(text)
self.f.flush()
if __name__ == "__main__":
root = tk.Tk()
app = ClientGUI(root)
root.mainloop()
关键代码解析:

功能:把每个字符的 ASCII 码 +8 加密,-8 解密
作用:简单对称加密,保证传输内容不直接显示明文

作用:让界面不卡死,后台持续监听网络消息

功能:安全地往聊天框追加内容
特点:自动滚动到最新消息
LLM代码的结果图片

LLM生成代码的优点:
1.在同时开启服务端和客户端时,在关闭服务端时,客户端会弹出“连接失败”提示并退出程序,同时,服务器未连接时禁止发送,不会报错崩溃,给用户增强了使用体验;
2.LLM生成的代码容错和异常处理更加完善,鲁棒性大大增强;
3.生成的代码结构清晰,代码趋于模块化;
4.LLM生成的代码引入多线程,收发互不干扰,实现双工实时通信,不会卡死界面。
上传代码云
实验3代码
实验3LLM生成代码


三. 实验过程中遇到的问题和解决过程
问题1.与同学Ping通时,无法正常连接上。
问题1解决方案:防火墙拦截了Ping通的请求,将防火墙关闭即可连接。
问题2.与同学连接进行正常的ip更改后,在进行测试时,却无法连接。
问题2解决方案:在大家连接同一个学校的网络时,有不同同学的学号的末尾时相同的,这样会导致另一个同学在连接时会导致报错,解决方法时连接另一个同学的网络热点进行操作。
问题3.在查询ipconfig时会提示“"ipconfig"不是内部或外部命令,也不是可运行的程序或批处理文件”
问题3解决方案:可能误删其文件等,需要在命令提示符中输入完整路径,如:C:\Windows\System32\ipconfig
四.其他(感悟、思考等)
在本次 Socket 网络通信实验中,我了解 TCP 套接字的通信原理,利用 Python 实现了带加密与日志记录的双人通信程序。同时,通过不断学习和同学帮助,我也学会了 IP 地址查询与配置。学习LLM生成后的代码后,也进一步理解了单线程通信与多线程通信的原理。
参考资料
浙公网安备 33010602011771号