20191218 2019-2020-2 《Python程序设计》实验三报告
课程:《Python程序设计》
班级: 1912
姓名: 唐启恒
学号:20191218
实验教师:王志强
实验日期:2021年5月29日
必修/选修: 公选课
1.实验内容
创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
(1)创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;
(2)要求包含文件的基本操作,例如打开和读写操作。
(3)要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中。
(4)程序代码托管到码云。
2. 实验过程及结果
(1)设置好SM2算法的相关环境
private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
public_key ='B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207'
sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)
(2)设置好服务器,等待客户端连接
-
客户端
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() port = 8005 s.bind((host, port)) s.listen()
-
服务端
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() port = 8005 c.connect((host, port))
(3)客户端向服务端传输文件
-
客户端
prompt = input("请输入要传输的文件名:") c.sendall(prompt.encode()) file = open(prompt, 'r+') text = file.read() text = text.encode('utf-8')
-
服务端
conn, address = s.accept() name = conn.recv(1024) print("来自", address, "的文件:", name.decode()) data = conn.recv(1024)
(4)对文件加密并存储到服务端中
-
文件加密
enc_data = sm2_crypt.encrypt(text) c.sendall(enc_data) file.close() data = c.recv(1024) print("来自" + host + "的信息:", data.decode()) c.sendall("收到".encode()) name = c.recv(1024)
-
文件存储
name = input("请填写解密后明文的文件名称:") f = open(name, "w+") dec_data = sm2_crypt.decrypt(data) dec_data = dec_data.decode() f.write(dec_data) f.close() print("来自", address, "加密的信息:", data, "解密后已保存为" + name + "文件") conn.sendall("服务器已经收到了数据内容,准备传输文件,注意接收!".encode())
运行过程截图
3. 实验过程中遇到的问题和解决过程
- 问题1:无法导入AES算法所在的Crypto库
-
问题1解决方案:尝试多次无果,上网查找CSDN对应的解决方案,最终还是没能成功解决问题,于是将AES加密换成了SM2加密算法,发现其对应的库通过pip安装后可以正常使用
-
问题2:可能会遇到电脑中文件阻止连接的情况
-
问题2解决方案:可以关闭防火墙对其的监视
-
问题3:读入文件时出现报错
-
问题3解决方案:读取文件时,文件内容必须是英文的,去掉text.txt文件中的中文字符就可以正常运行了
-
问题4:由于目标计算机积极拒绝,无法连接
-
问题4解决方案:将服务器和客户端开放的顺序调换一下,先开服务端,再开客户端即可
-
问题5:'utf-8' codec can't decode byte 0xe5 in position 2
-
问题5解决方案:调用bytes.decode()时添加参数errors='ignore'即可
其他(感悟、思考等)
本次实验了解了socket通信的过程,并动手实践实现了一个基于TCP的简单socket通信。在这次实践过程中遇到了许许多多环境配置出错的情况,大大降低了效率,像导入crypto库中的AES就足足花了几个小时,仔细检查后发现和我电脑中在不同路径安装了多个版本python有关,每次pip安装时的路径与我预想的有所出入。
参考资料
- from Crypto.Cipher import AES ImportError: No module named Crypto.Cipher
- python3.7下使用from Crypto.Cipher import AES时发生错误:ModuleNotFoundError: No module named 'Crypto'
- 【PyCharm】三方库安装后,import提示找不到对应模块
- Python错误:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte...
- gmssl-python 支持国密算法的 Python 加密包
- Python"由于目标计算机积极拒绝,无法连接。"错误解决
- UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xe5 in position 0: unexpected end of data