20193415 实验三《Python程序设计》实验报告
20193415 2020-2021-2 《Python程序设计》实验三报告
课程:《Python程序设计》
班级: 1934
姓名: 简文翔
学号: 20193415
实验教师:王志强
实验日期:2021年5月24日
必修/选修:公选课
1. 实验内容
- 创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
2. 实验过程及结果
(1) 创建服务端
-
创建套接字,绑定套接字到本地IP与端口
# 参数1:服务器之间网络通信;参数2:流式socket, for TCP s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定:localhost = 127.0.0.1, port = 33624 s.bind(('127.0.0.1', 33624))
-
开始监听连接并接受客户端的请求
要求服务端在特定端口监听多个客户请求,故设置listen()的参数为5
(在拒绝连接之前,操作系统可以挂起的最大连接数量为5)s.listen(5) conn, address = s.accept()
-
接收传来的数据,并发送给对方数据
data = conn.recv(1024) # 接受套接字的数据,最大数据量为1024 print(data.decode("utf-8")) conn.sendall(("服务端接收到了数据:" + str(data.decode("utf-8"))).encode("utf-8"))
-
将接受到的数据解密并写入txt文件,关闭套接字
f = open("Server.txt", 'w', encoding="utf-8") f.write((base64.b64decode(data).decode("ascii"))) s.close()
(2) 创建客户端
-
创建套接字,连接远端地址
# 参数1:服务器之间网络通信;参数2:流式socket, for TCP s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 33624))
-
打开txt文件读取内容并进行base64加密
f = open("Client.txt", 'r', encoding="utf-8") message = f.read() print("加密后的数据为:" + str(base64.b64encode(message.encode("utf-8"))))
首先,从“Client.txt”文件中读取的数据是字符串,而base64.b64encode()加密函数的参数是字节流,故调用encode("utf-8")将读取的数据转化为字节流;
经base64.b64encode()加密后的数据变为字节流,不能直接与字符串一同被print,故利用str()转化为字符串 -
连接后发送数据和接收数据,关闭套接字
s.sendall(base64.b64encode(message.encode("utf-8"))) # 发送加密数据 data = s.recv(1024) print(data.decode()) s.close()
(3) 实验结果
- 客户端能够正常收到服务端数据,且服务端收到的数据正确
(4) 程序代码托管到码云
- 仓库页面:
代码截图
3. 实验过程中遇到的问题和解决过程
-
问题1:报错:应为类型'bytes',但得到的是'str'
解决方案:conn.sendall()函数的参数必须是字节流,应该用bytes()转化
-
问题2:报错:由于目标计算机积极拒绝,无法连接
解决方案:往往出现于报错后修改完代码再次运行,重启Pycharm后即可正常运行
-
问题3:报错:string argument without an encoding
解决方案:顾名思义,第20行中的
str(Plaintext)
改为str(Plaintext).encode("utf-8")
其他(感悟、思考等)
本次实验是利用Socket编程技术实现服务端与客户端的通信过程,对我来说都是很新奇的知识。实验的代码倒不难写,但是里面的通信过程是非常具有典型性的,能够掌握这样一种通信的过程对我来说是非常有帮助。在编写简简单单的一句conn.sendall(("服务端接收到了数据:" + str(data.decode("utf-8"))).encode("utf-8"))
时,我也是进行了非常多次的尝试才使它不报错,这使我对函数的参数与输出的数据编码有了深层次的理解。