20242126 实验三《Python程序设计》实验报告
20242126 2024-2025-2 《Python程序设计》实验三报告
课程:《Python程序设计》
班级: 2421
姓名: 邹清楠
学号:20242126
实验教师:王志强
实验日期:2025年4月16日
必修/选修: 公选课
一. 实验内容
- 创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
二. 实验过程及结果
1.服务端部分
(1) 导入os库和socket库
import socket
import os
(2)定义加密函数
这里使用了异或加密,仅为对文本进行加密的一个示例。当然也可以使用其他的加密方法。
def xor(data, key):
#确保数据为byte类型
if isinstance(data, str):
dabin = data.encode('utf-8')
else:
dabin = data
kebin = key.encode('utf-8')
result = bytearray()
length = len(kebin)
#循环用密钥加密数据并存入reslut
#这样一来,当密钥比数据短时仍然可以加密
for i, byte in enumerate(dabin):
result.append(byte ^ kebin[i % length])
return bytes(result)
# 根据输入类型决定返回类型
return result.decode('utf-8', errors='ignore') if isinstance(data, str) else bytes(result)
(3)基本配置环节
key = "NORREICH" #定义密钥
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建TCP套接字
server.bind(('localhost', 9999)) #绑定IP和端口,这里用了本机的IP
server.listen(5)
print("服务器已启动,监听中...")
(4)主体部分
主题部分使用try语句,方便记录异常情况
try:
while True: #进入循环,不断进行两端的信息发送
client, address = server.accept()
# 接受客户端连接,返回客户端socket对象和地址信息
print(f"客户端 {address} 已连接") # 打印客户端连接信息
try:
proc_data = client.recv(1024) #接受最多1024字节的信息
if not proc_data: #收到空数据则跳过
continue
#对数据进行加密
deproc_data = xor(proc_data, key).decode('utf-8', errors='ignore')
if deproc_data.startswith("FILE"): #当客户端发送FILE开头的文本时,则开始接收文件
filename = deproc_data[4:].strip() #切割获得文件名
save = os.path.join("D:\\Temp", filename) #构造文件保存路径,这里预先填好了一个
print(f"FILE命令识别成功,开始接收文件 {filename}")
#以二进制写入模式打开文件(其实是创建了一个新文件)
with open(save, 'wb') as f:
while True:
chunk = client.recv(4096)
if not chunk:
break
de_chunk = xor(chunk, key)
# 检查是否收到结束标记
try:
if de_chunk.decode('utf-8') == "EOF":
break
except:
pass
#将数据写入文件
f.write(de_chunk)
print("文件接收完成")
response = xor("服务器回应:文件接受成功!", key)
client.send(response)
else:#普通消息
print(f"客户端消息: {deproc_data}")
response2 = input("请输入向客户端发送的消息:")
response = xor(response2, key)
client.send(response)
except Exception as e:
#捕获并打印异常信息
print(f"发生错误:{e}")
finally:
client.close()
except KeyboardInterrupt:
print("服务器关闭")
finally:
server.close()
2.客户端部分
客户段部分与服务器端相差不大,主要区别在主体部分
if user.upper().startswith("FILE"):#开始传输文件
filename = user[4:].strip()
path = os.path.join("D:\\Temp\\Multiwheel", filename)
if not os.path.exists(path):
print(f"文件不存在:{filename}")
continue
# 发送文件头信息
head = f"FILE{filename}"
de_head = xor(head, key)
client.send(de_head)
print(f"开始发送文件:{filename}")
with open(path, 'rb') as f:
#以二进制只读模式打开文件
while True:
data = f.read(4096)
if not data:
# 发送结束标记
client.send(xor("EOF", key))
break
de_data = xor(data, key)
client.send(de_data)
print("文件发送完成")
# 等待服务器确认
enc = client.recv(1024)
response = xor(enc, key).decode('utf-8')
print(f"服务器响应: {response}")
以下是运行截图:
首先我在客户端的预定目录里存放了一个叫1.txt的文本文档

然后,开启服务端和客户端

在客户端中输入“FILE1.txt”,客户端接到命令传输文件,服务端显示接受成功

进入服务端的保存路径,果然有文件存在

接下来进行普通消息传输测试:


确保两台电脑同时连接同一个WIFI,在cmd中运行ipconfig命令,将程序中的IPv4地址换为WIFI的

一台电脑先运行服务端,另一台电脑运行客户端,传输消息成功

3.实验过程中遇到的问题和解决过程
-
问题1:服务端一直显示监听中,无法对数据做出反应
问题1解决方案:在之前已经使用了server.accept(),使得端口被占据,删掉代码即可 -
问题2:有时两端连接之后,服务端无法显示任何内容
问题2解决方案:显示问题,其实可以进行操作,重新进入后可以在历史记录中看到记录 -
问题3:运行客户端时显示“由于目标计算机积极拒绝,无法连接。”
问题3解决方案:确保服务端已经在运行,然后再运行客户端
4.感悟和思考
- 通过这次实验,我学会了使用try语句,用try语句写出的代码更加稳定可靠。对于文件传输,还可以使其更为人性化,比如可以从用户输出里获取文件发送和保存路径。最后,我没有添加退出功能,只能强制退出,应当改进。
浙公网安备 33010602011771号