python数据库编程实验报告_20183122 实验三《Python程序设计》实验报告

20183122 2019-2020-2 《Python程序设计》实验三报告

课程:《Python程序设计》

班级: 1831

姓名: 陈介

学号:20183122

实验教师:王志强

实验日期:2020年5月16日

必修/选修: 公选课

1.实验内容

1)、创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。

2)、实现客户端和服务器端的文件(支持任意类型的文件,如txt、mp4、jpg、png、html等)发送和接收,发送的数据采用DES加密。

2. 实验过程及结果

1)、搭建大致框架,在客户端与服务器端建立连接,服务器端实现一直工作,不受客户端异常退出导致传输异常的影响。

2)、在发送端进行数据的处理。

a、构造报头,包括要发送的文件名,操作的文件大小等信息;

cmd = input("请输入命令:")

if cmd == "exit":

exit(0)

try:

action, filename = cmd.strip().split(' ')

filesize = os.path.getsize(filename)

except:

print("命令错误或找不到文件")

break

b、先利用json模块将报头字典转化成比特流,再利用struct模块封包报头比特流长度,使其长度固定为4字节;

file_info_bytes = json.dumps(file_info).encode()

len_header = len(file_info_bytes)

res = struct.pack("i", len_header)

c、完成上述步骤后就可以发送数据了:以二进制只读的方式打开文件,逐行加密并发送,再利用md5.updata()方法更新摘要值;

d、发送完成后等待接收端校验并发回反馈

3)、在接收端进行数据的处理。

a、接收4比特的报头部分长度的封包;

b、对前一步获得的数据进行解包,得到比特流长度,再根据长度接收报头,利用json模块将其还原成字典,得到完整的报头;

res = struct.unpack("i", len_header)

···

header = json.loads(info_header)

c、接收数据并对数据进行校验,将校验的结果发送给发送方;

recv_md5: str = conn.recv(1024).decode()

if md5.hexdigest() == recv_md5:

print("文件完整性验证通过")

print('*' * 50)

conn.send("文件完整性验证通过".encode())

else:

print("文件完整性验证失败,发送过程中文件可能丢失或被篡改!!!")

print('*'*50)

conn.send("文件完整性验证失败,发送过程中文件可能丢失或被篡改!!!".encode())

运行结果:

运行前:(可以看到,运行前服务器端对应的文件夹中没有文件):

1939988-20200520173033137-690629000.png

服务器端运行中(可以看到即使客户端异常退出服务器端也能继续运行):

1939988-20200520175503666-1708165244.png

客户端运行结果:

1939988-20200520175819123-1901949279.png

运行后,服务器端的文件夹中多了相应的内容:

1939988-20200520175941907-1226933626.png

3. 实验过程中遇到的问题和解决过程

问题1:自己写的加密解密模块导入失败

问题1解决方案:将自己的模块所在的文件夹设定为Source root型

问题2:黏包:连续send时接收端分不清边界

问题2解决方案:

发送端:

先发送报头长度

再编码报头内容并发送

最后发送数据

接收端:

接受报头长度

按照接收的长度接收报头并解包

最后接收数据

其他

服务器端:https://gitee.com/konelee/python_programming/blob/master/实验三服务器端.py

客户端:https://gitee.com/konelee/python_programming/blob/master/实验三客户端.py

在实验初期我并不知道会存在黏包的现象,因为当时我传送的都是比较小的文件,接收端一次就可以完全接收,后来我用较大的mp4文件做实验,发现接收端在recv()处阻塞了,但此时它本应收到来自发送端的验证文件完整性的摘要的,查找资料之后我才得知出现此现象是由于黏包。刚开始研究黏包现象的时候,我发现time.sleep()可以解决黏包问题,但这种方式实在太low,极其浪费资源和时间,使传输效率大打折扣;于是我寻找到了利用构造报头来实现的解决黏包,这种方式解决黏包问题十分高效,对传输效率基本没有影响。

来源:https://www.cnblogs.com/konelee/p/12923289.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值