20242118 实验三《Python程序设计》实验报告
20242118 2024-2025-2 《Python程序设计》实验三报告
课程:《Python程序设计》
班级:2421
姓名:符馨琰
学号:20242118
实验教师:王志强
实验日期:2025年4月16日
必修/选修:公选课
一、实验内容
创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
具体要求如下:
1.创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;
2.要求包含文件的基本操作,例如打开和读写操作;
3.要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中;
4.程序代码托管到码云。
二、实验过程及结果
(注:使用“添加代码”后代码显示不正常,故报告中四个代码均折叠)
1.创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;
(1)打开终端,输入ipconfig获取自己的ipv4地址;

(2)分别编写服务端与客户端的代码兵运行;
服务端:
点击查看代码
import socket
import threading
import os
import time
def clear_screen():
"""清屏功能"""
os.system('cls' if os.name == 'nt' else 'clear')
def handle_client(client_socket, client_address):
print(f"收到来自 {client_address} 的连接")
try:
# 创建一个线程来处理服务器输入并发送给客户端
input_thread = threading.Thread(
target=server_input,
args=(client_socket,)
)
input_thread.daemon = True
input_thread.start()
while True:
# 接收客户端消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print(f"\r\n客户端说: {data}")
print("服务端说: ", end='', flush=True) # 重新显示输入提示
except Exception as e:
print(f"\n发生错误: {e}")
finally:
client_socket.close()
print("\n客户端连接已关闭")
def server_input(client_socket):
"""处理服务器输入并发送到客户端"""
try:
while True:
message = input("服务端说: ")
if message.lower() == 'exit':
break
elif message.lower() == 'clear':
clear_screen()
print("聊天已清屏")
continue
client_socket.send(message.encode('utf-8'))
except Exception as e:
print(f"\n发送消息时出错: {e}")
def start_server():
# 创建服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置端口复用,这样服务器意外断开后可以立即重用端口
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定地址和端口
host = 'localhost'
port = 12345
server_socket.bind((host, port))
# 开始监听
server_socket.listen(1)
clear_screen()
print(f"服务器正在监听 {host}:{port}")
print("输入 'exit' 退出聊天")
print("=" * 50)
while True:
# 接受客户端连接
client_socket, client_address = server_socket.accept()
# 创建一个新线程来处理客户端连接
client_thread = threading.Thread(
target=handle_client,
args=(client_socket, client_address)
)
client_thread.daemon = True
client_thread.start()
if __name__ == "__main__":
start_server()
点击查看代码
import socket
import threading
import os
import time
def clear_screen():
"""清屏功能"""
os.system('cls' if os.name == 'nt' else 'clear')
def receive_messages(client_socket):
"""接收来自服务器的消息"""
try:
while True:
data = client_socket.recv(1024).decode('utf-8')
if not data:
print("\n服务器已断开连接")
break
print(f"\r\n服务端说: {data}")
print("客户端说: ", end='', flush=True) # 重新显示输入提示
except Exception as e:
print(f"\n接收消息时出错: {e}")
finally:
client_socket.close()
def start_client():
# 创建客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务器
host = 'localhost'
port = 12345
try:
client_socket.connect((host, port))
clear_screen()
print(f"已连接到服务器 {host}:{port}")
print("输入 'exit' 退出聊天")
print("=" * 50)
# 创建接收消息的线程
receive_thread = threading.Thread(
target=receive_messages,
args=(client_socket,)
)
receive_thread.daemon = True
receive_thread.start()
# 主线程负责发送消息
while True:
message = input("客户端说: ")
if message.lower() == 'exit':
break
elif message.lower() == 'clear':
clear_screen()
print("聊天已清屏")
continue
client_socket.send(message.encode('utf-8'))
except Exception as e:
print(f"连接或发送消息时出错: {e}")
finally:
client_socket.close()
print("已断开与服务器的连接")
if __name__ == "__main__":
start_client()

2.加入包含文件的基本操作,例如打开和读写操作。
服务端:
点击查看代码
import socket
import os
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
# 密钥和IV
FIXED_KEY = b"MySecretKey12345"
FIXED_IV = b"InitVector123456"
# 解密函数
def decrypt_data(data):
cipher = AES.new(FIXED_KEY, AES.MODE_CBC, FIXED_IV)
decrypted_data = unpad(cipher.decrypt(data), AES.block_size)
return decrypted_data
# 主函数
def start_server():
# 创建服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 服务器设置
host = 'localhost'
port = 9999
server_socket.bind((host, port))
server_socket.listen(1)
print(f"服务器已启动,监听地址: {host}:{port}")
# 主循环
while True:
# 等待连接
client_socket, client_address = server_socket.accept()
print(f"客户端已连接: {client_address}")
# 接收文件名
filename = client_socket.recv(1024).decode('utf-8')
print(f"接收文件: {filename}")
# 接收文件大小
file_size = int(client_socket.recv(1024).decode('utf-8'))
# 接收加密数据
encrypted_data = b''
remaining = file_size
while remaining > 0:
chunk = client_socket.recv(min(4096, remaining))
if not chunk:
break
encrypted_data += chunk
remaining -= len(chunk)
# 解密并保存
print("正在解密...")
decrypted_data = decrypt_data(encrypted_data)
# 保存文件
os.makedirs("接收文件", exist_ok=True)
save_path = os.path.join("接收文件", filename)
with open(save_path, 'wb') as f:
f.write(decrypted_data)
print(f"文件已保存: {save_path}")
client_socket.send("完成".encode('utf-8'))
client_socket.close()
print("连接已关闭")
# 程序入口
if __name__ == "__main__":
start_server()
点击查看代码
import socket
import os
import sys
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
# 密钥和IV
FIXED_KEY = b"MySecretKey12345"
FIXED_IV = b"InitVector123456"
# 加密函数
def encrypt_data(data):
cipher = AES.new(FIXED_KEY, AES.MODE_CBC, FIXED_IV)
padded_data = pad(data, AES.block_size)
encrypted_data = cipher.encrypt(padded_data)
return encrypted_data
# 发送文件函数
def send_file(file_path):
# 检查文件是否存在
if not os.path.exists(file_path):
print(f"错误: 文件不存在: {file_path}")
return
# 创建套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务器
host = 'localhost'
port = 9999
client_socket.connect((host, port))
print(f"已连接到服务器: {host}:{port}")
# 发送文件名
filename = os.path.basename(file_path)
client_socket.send(filename.encode('utf-8'))
# 读取文件
with open(file_path, 'rb') as f:
file_data = f.read()
# 加密文件
print("正在加密...")
encrypted_data = encrypt_data(file_data)
# 发送文件大小
client_socket.send(str(len(encrypted_data)).encode('utf-8'))
# 发送加密数据
client_socket.sendall(encrypted_data)
print("文件发送完成")
# 接收服务器响应
response = client_socket.recv(1024).decode('utf-8')
print(f"服务器回复: {response}")
# 关闭连接
client_socket.close()
print("连接已关闭")
# 程序入口
if __name__ == "__main__":
if len(sys.argv) != 2:
print("用法: python simple_aes_client.py <文件路径>")
else:
file_path = sys.argv[1]
send_file(file_path)

接收文件

源代码上传gitee

三. 实验过程中遇到的问题和解决过程
问题1:网络不同无法连接
问题1解决方案:主机连接同一热点
问题2:代码正确但一直无法监听客户端
问题3解决方案:关闭电脑防火墙
四.其他(感悟、思考等)
1.实验三将理论知识转化为实际应用,提高了我的实践能力;
2.了解了如何对数据进行加密操作,进行加密通讯。
五、参考资料
《零基础学Python》
浙公网安备 33010602011771号