20244319 实验三《Python程序设计》实验报告
20244319 2024-2025-2 《Python程序设计》实验三报告
课程:《Python程序设计》
班级:2443
姓名:梁悦
学号:20244319
实验教师:王志强
实验日期:2025年4月16日
必修/选修: 公选课
一、实验内容
创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
二、实验过程及结果
(一)创建服务端和客户端,
1.查询IP地址
在cmd终端中调用ipconfig函数(此处查询的是搭档的IP地址)

2.实验代码
服务端代码:
点击查看代码
# -*- coding: utf-8 -*-
import socket
# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_address = ('192.168.43.159', 8888)
server_socket.bind(server_address)
# 监听连接
server_socket.listen(1)
print('服务器正在监听 {}:{}'.format(*server_address))
# 接受客户端连接
client_socket, client_address = server_socket.accept()
print('接受来自 {} 的连接'.format(client_address))
while True:
# 接收客户端消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('客户端说: {}'.format(data))
# 发送消息给客户端
message = input('请输入要发送给客户端的消息: ')
client_socket.send(message.encode('utf-8'))
if input("是否要继续?Y/N")=="N":
break
# 关闭连接
client_socket.close()
server_socket.close()
客户端代码:
点击查看代码
# -*- coding: utf-8 -*-
import socket
# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
server_address = ('192.168.10.48',8888)
client_socket.connect(server_address)
while True:
# 发送消息给服务器
message = input('请输入要发送给服务器的消息: ')
client_socket.send(message.encode('utf-8'))
# 接收服务器消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('服务器说: {}'.format(data))
if (input("是否继续Y/N?")=="N"):
break
# 关闭连接
client_socket.close()
3.运行结果截图:
服务端(此处搭档已连接我的热点,故其ip地址为196.168.43.120):

客户端:

(二)要求包含文件的基本操作,例如打开和读写操作(选做)
服务端代码:
点击查看代码
import socket
# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_address = ('192.168.43.159', 8888)
server_socket.bind(server_address)
# 监听连接
server_socket.listen(1)
print('服务器正在监听 {}:{}'.format(*server_address))
# 接受客户端连接
client_socket, client_address = server_socket.accept()
print('接受来自 {} 的连接'.format(client_address))
# 打开文件以记录消息
with open('server_messages.txt', 'a', encoding='utf-8') as server_file:
while True:
# 接收客户端消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('客户端说: {}'.format(data))
server_file.write(f'客户端发送: {data}\n')
# 发送消息给客户端
message = input('请输入要发送给客户端的消息: ')
client_socket.send(message.encode('utf-8'))
server_file.write(f'发送给客户端: {message}\n')
if input("是否要继续?Y/N") == "N":
break
# 关闭连接
client_socket.close()
server_socket.close()
客户端代码:
点击查看代码
import socket
# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
server_address = ('192.168.10.48', 8888)
client_socket.connect(server_address)
# 打开文件以记录消息
with open('client_messages.txt', 'a', encoding='utf-8') as client_file:
while True:
# 发送消息给服务器
message = input('请输入要发送给服务器的消息: ')
client_socket.send(message.encode('utf-8'))
client_file.write(f'发送给服务器: {message}\n')
# 接收服务器消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('服务器说: {}'.format(data))
client_file.write(f'服务器回复: {data}\n')
if input("是否继续Y/N?") == "N":
break
# 关闭连接
client_socket.close()
截图:

(三)要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中
1.安装 pycryptodome 库

2.加密插件(老师提供)
服务端代码:
点击查看代码
import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
# 创建服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
address = ('localhost', 9999)
server_socket.bind(address)
# 开始监听
server_socket.listen()
print("服务器正在监听端口 9999...")
try:
# 接收客户端连接
conn, addr = server_socket.accept()
# 接收加密数据
encrypted_data = conn.recv(4096) # 根据需要调整接收缓冲区大小
print("接收到加密数据,开始解密...")
# AES 加密参数
key = b'1234567890987654' # 16 字节密钥
iv = b'1234567890987654' # 初始化向量
# 创建 AES 解密器
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
decrypted_data = cipher.decrypt(encrypted_data)
# 去除填充
try:
decrypted_data = unpad(decrypted_data, AES.block_size)
except ValueError as e:
print(f"解密失败:{e}")
decrypted_data = "解密失败".encode("utf-8") # 使用 UTF-8 编码将字符串转换为 bytes
# 保存解密后的数据到文件
with open("decrypted_output.txt", "wb") as f:
f.write(decrypted_data)
print("解密完成,数据已保存到 decrypted_output.txt")
finally:
# 关闭服务器套接字
server_socket.close()
客户端代码:
点击查看代码
import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
try:
# 创建客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 定义服务器地址和端口
server_address = ('localhost', 9999)
# 连接到服务器
client_socket.connect(server_address)
print("已连接到服务器")
# AES 加密参数
key = b'1234567890987654' # 16 字节密钥
iv = b'1234567890987654' # 初始化向量
# 读取文件内容
with open("decrypted_input.txt", "rb") as f:
data = f.read()
# 创建 AES 加密器
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
# 对数据进行加密,确保数据长度是块大小的倍数
padded_data = pad(data, AES.block_size)
encrypted_data = cipher.encrypt(padded_data)
# 发送加密数据
client_socket.sendall(encrypted_data)
print("加密数据已发送到服务器")
except socket.error as e:
print(f"套接字错误: {e}")
except FileNotFoundError:
print("文件未找到")
except Exception as e:
print(f"发生其他错误: {e}")
finally:
# 关闭客户端套接字
client_socket.close()
截图:

(四)程序代码托管到码云

三、 实验过程中遇到的问题和解决过程
- 问题1:搭档安装不了pycryptodome库
- 问题1解决方案:改用异或加密
服务端代码:
点击查看代码
import socket
# 创建服务器套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
address = ('192.168.43.159', 9999)
server_socket.bind(address)
# 开始监听
server_socket.listen()
print("服务器正在监听端口 9999...")
try:
# 接收客户端连接
conn, addr = server_socket.accept()
# 接收加密数据
encrypted_data = conn.recv(4096) # 根据需要调整接收缓冲区大小
print("接收到加密数据,开始解密...")
# 异或加密密钥
key = b'1234567890987654'
# 异或解密
decrypted_data = bytes([encrypted_data[i] ^ key[i % len(key)] for i in range(len(encrypted_data))])
# 保存解密后的数据到文件
with open("decrypted_output.txt", "wb") as f:
f.write(decrypted_data)
print("解密完成,数据已保存到 decrypted_output.txt")
finally:
# 关闭服务器套接字
server_socket.close()
客户端代码:
点击查看代码
import socket
# 尝试创建 decrypted_input.txt 文件
try:
with open('decrypted_input.txt', 'w') as f:
pass
except Exception as e:
print(f"创建文件失败,原因:{e}")
try:
# 创建客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 定义服务器地址和端口
server_address = ('192.168.10.48', 9999)
# 连接到服务器
client_socket.connect(server_address)
print("已连接到服务器")
# 异或加密密钥
key = b'1234567890987654'
# 读取文件内容
with open("decrypted_input.txt", "rb") as f:
data = f.read()
# 异或加密
encrypted_data = bytes([data[i] ^ key[i % len(key)] for i in range(len(data))])
# 发送加密数据
client_socket.sendall(encrypted_data)
print("加密数据已发送到服务器")
except socket.error as e:
print(f"套接字错误: {e}")
except FileNotFoundError:
print("文件未找到")
except Exception as e:
print(f"发生其他错误: {e}")
finally:
# 关闭客户端套接字
client_socket.close()
运行结果截图:


四、其他(感悟、思考等)
1.机魂不悦,无法战胜(拜orz);
2.要搞清楚服务端IP是哪个,不然无法建立连接(SOS ;
3.学会了如何折叠代码,开心~~。
参考资料
- 《零基础学Python》(2018 明日科技编著)
浙公网安备 33010602011771号