学号:20241227曹鹏泰 2024-2025-3《Python程序设计》实验三报告
课程:《Python程序设计》
班级: 2412
姓名: 曹鹏泰
学号:20241227
实验教师:王志强
实验日期:2025年4月22日
必修/选修:公选课
一.实验内容:
(1)内容:创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
(2)要求:
1>.创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;
2>.要求包含文件的基本操作,例如打开和读写操作。
3>.要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中。
4>.程序代码托管到码云。
注:在华为ECS服务器(OpenOuler系统)和物理机(Windows/Linux系统)上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
二.实验过程及结果:https://gitee.com/uchiha-p/xiao-organization.git;)
1.实现连接和通信功能:(这段代码实现了一个简单的基于 TCP 协议的服务器端程序,能够与客户端建立连接并进行简单的双向文本通信。)
实验代码:
服务端
# -*- coding: utf-8 -*-
#该 Python 脚本的编码格式为 UTF-8,这样脚本中就可以正确处理包含中文字符等Unicode字符的内容。
import os
# 文件名: Server2025
# 描 述:
# 作 者: besti
# 日 期: 2025/4/15
# Have you ever seen Los Angeles at 4 a.m?
import socket
# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_address = ('192.168.43.78', 9999)
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()
参数“1” 表示允许的最大未完成连接数,即同时可以等待处理的客户端连接请求数量。然后打印出服务器正在监听的地址和端口信息。
客户端
# -*- coding: utf-8 -*-
# 文件名: Client2025
# 描 述:
# 作 者: 20241227曹鹏泰
# 日 期: 2025/4/22
# Have you ever seen Los Angeles at 4 a.m?
import socket
# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
server_address = ('192.168.43.78', 9999)
# 绑定了服务器的IP地址和端口
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()
实验结果:



2.文件的打开和传送:
实验代码:
服务端
# -*- coding: utf-8 -*-
import os
# 文件名: Server2025
# 描 述:
# 作 者: besti
# 日 期: 2025/4/15
# Have you ever seen Los Angeles at 4 a.m?
import socket
# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_address = ('192.168.43.78', 9999)
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))
# 将客户端消息写入文件
try:
with open('client_messages.txt', 'a', encoding='utf-8') as file:
file.write(data + '\n')
except Exception as e:
print(f'写入文件时出错: {e}')
# 发送消息给客户端
message = input('请输入要发送给客户端的消息: ')
client_socket.send(message.encode('utf-8'))
if input("是否要继续?Y/N") == "N":
break
# 关闭连接
client_socket.close()
server_socket.close()
客户端
# -*- coding: utf-8 -*-
# 文件名: Client2025
# 描 述:
# 作 者: besti
# 日 期: 2025/4/15
# Have you ever seen Los Angeles at 4 a.m?
import socket
# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
server_address = ('192.168.43.78', 9999)
client_socket.connect(server_address)
while True:
choice = input('请选择操作:1. 发送消息;2. 发送文件内容;3. 退出:')
if choice == '1':
# 发送消息给服务器
message = input('请输入要发送给服务器的消息: ')
client_socket.send(message.encode('utf-8'))
elif choice == '2':
file_path = input('请输入要发送的文件路径: ')
try:
with open(file_path, 'r', encoding='utf-8') as file:
file_content = file.read()
client_socket.send(file_content.encode('utf-8'))
except FileNotFoundError:
print('文件未找到,请检查文件路径。')
elif choice == '3':
break
else:
print('无效的选择,请重新输入。')
# 接收服务器消息
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
print('服务器说: {}'.format(data))
# 关闭连接
client_socket.close()
在上述的 Python 代码中,当客户端选择发送文件内容时,输入的文件路径可以是绝对路径,也可以是相对路径(相对于运行客户端程序时的当前工作目录)。
例如,文件 “test.txt” 在 “C:\Users\username\Documents” 文件夹下,其完整路径就是 “C:\Users\username\Documents\test.txt”。
实验结果:



3.文件的加密
实验代码:
服务端:
# -*- coding: utf-8 -*-
import os
# 文件名: Server2025
# 描 述:
# 作 者: besti
# 日 期: 2025/4/15
# Have you ever seen Los Angeles at 4 a.m?
import socket
# 定义异或加密函数,定义了与客户端相同的加密密钥key。
def xor_encrypt_decrypt(data, key):
key_length = len(key)
encrypted = bytearray()
for i in range(len(data)):
encrypted.append(data[i] ^ key[i % key_length])
return bytes(encrypted)
# 加密密钥,要与客户端保持一致
key = b'secretkey'
# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_address = ('192.168.43.78', 9999)
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:
# 接收客户端消息,在接收客户端消息时,调用 xor_encrypt_decrypt 函数对加密数据进行解密,然后打印并写入文件。
encrypted_data = client_socket.recv(1024)
if not encrypted_data:
break
data = xor_encrypt_decrypt(encrypted_data, key).decode('utf-8')
print('客户端说: {}'.format(data))
# 将客户端消息写入文件
try:
with open('client_messages.txt', 'a', encoding='utf-8') as file:
file.write(data + '\n')
except Exception as e:
print(f'写入文件时出错: {e}')
# 发送消息给客户端,在发送消息给客户端时,调用 xor_encrypt_decrypt 函数对消息进行加密,然后发送加密后的消息。
message = input('请输入要发送给客户端的消息: ')
encrypted_message = xor_encrypt_decrypt(message.encode('utf-8'), key)
client_socket.send(encrypted_message)
if input("是否要继续?Y/N") == "N":
break
# 关闭连接
client_socket.close()
server_socket.close()
客户端:
# -*- coding: utf-8 -*-
# 文件名: Client2025
# 描 述:
# 作 者: besti
# 日 期: 2025/4/15
# Have you ever seen Los Angeles at 4 a.m?
import socket
# 定义异或加密函数
def xor_encrypt_decrypt(data, key):
key_length = len(key)
encrypted = bytearray()
for i in range(len(data)):
encrypted.append(data[i] ^ key[i % key_length])
return bytes(encrypted)
# 加密密钥
key = b'secretkey'
# 创建 socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
server_address = ('192.168.43.78', 9999)
client_socket.connect(server_address)
while True:
choice = input('请选择操作:1. 发送消息;2. 发送文件内容;3. 退出:')
if choice == '1':
# 发送消息给服务器,在发送消息或文件内容时,调用 xor_encrypt_decrypt 函数对数据进行加密,然后发送加密后的数据。
message = input('请输入要发送给服务器的消息: ')
encrypted_message = xor_encrypt_decrypt(message.encode('utf-8'), key)
client_socket.send(encrypted_message)
elif choice == '2':
file_path = input('请输入要发送的文件路径: ')
try:
with open(file_path, 'rb') as file:
file_content = file.read()
encrypted_content = xor_encrypt_decrypt(file_content, key)
client_socket.send(encrypted_content)
except FileNotFoundError:
print('文件未找到,请检查文件路径。')
elif choice == '3':
break
else:
print('无效的选择,请重新输入。')
# 接收服务器消息,在接收服务器消息时,同样调用 xor_encrypt_decrypt 函数对加密数据进行解密,然后打印解密后的消息。
encrypted_data = client_socket.recv(1024)
if not encrypted_data:
break
data = xor_encrypt_decrypt(encrypted_data, key).decode('utf-8')
print('服务器说: {}'.format(data))
# 关闭连接
client_socket.close()
实验结果:


“xor_encrypt_decrypt” 函数实现了异或加密和解密的功能。
由于异或运算的特性,加密和解密使用的是同一个函数。
三.实验过程中遇到的问题和解决过程:
问题1:指定文件的路径错误
输入了D:\projects\练习一,显示错误。
解决方法:D:\projects\练习一是一个路径,但它可能是一个文件夹路径。如果要读取这个文件夹下的文件,还需要在这个路径基础上加上文件名和文件扩展名。
完整路径应该是D:\projects\练习一\test.txt。(同时要注意去掉双引号)
问题2:加密算法错误

未安装相关的pycharm插件。
解决方法:终端运行pip install pycryptodome,或者采用异或加密的方法,只是安全性不高。
四.其他(感悟、思考等)
对Socket 套接字在 TCP 协议下的通信机制有了直观且深入的认识。服务端监听端口、等待连接,客户端发起连接请求,这种交互模式看似简单,
实则在实际代码编写时,需要仔细处理诸如连接建立、数据收发、异常处理等多个环节。
五.参考资料:深入理解Python密码学:使用PyCrypto库进行加密和解密 ;python 对文件进行异或运算

浙公网安备 33010602011771号