20181312 2019-2020-2 《Python程序设计》实验三报告
课程:《Python程序设计》
班级:1813
姓名:谢绎
学号:20181312
实验教师:王志强
实验日期:2020年5月16日
必修/选修:公选课
1.实验内容
创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP / UDP)进行通信。
2. 实验过程及结果
socket原理
-
什么是socket
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
-
套接字工作流程
-
服务器端初始化Socket
-
与端口绑定bind
-
对端口进行监听listen
-
调用accept阻塞
-
等待客户端连接
-
客户端初始化一个Socket
-
连接服务器connect
-
如果连接成功,就建立了客户端与服务器端的连接
-
客户端发送数据请求,服务器端接收请求并处理请求
-
服务器回应数据发送给客户端,客户端读取数据
-
关闭连接,一次交互结束
-
代码设计
-
客户端(client)
连接服务器
import socket p = socket.socket(socket.AF_INET, socket.SOCK_STREAM) p.connect(('127.0.0.1', 8080)) while 1: msg = encrypted_text #encrypted_text是经过DES加密后形成的二进制文本 #DES加密部分见下 print("从文件" + docu + "中读取到明文") print("明文经加密后发送的加密文本是: ", msg) # 防止输入空消息 if not msg: continue p.send(msg) break p.close()
DES加密部分 && doxc文件读取
from Cryptodome.Cipher import DES from docx import Document docu = r"C:UsersHPPCdesktop1813明文.docx" #文件储存路径,可以更改 def getText(filename): #函数将word文档中的文本以字符串形式呈现 doc = Document(filename) fullText = "" for para in doc.paragraphs: fullText = fullText + para.text + ' ' return fullText def pad(text): #由于加密文本text必须为8的倍数,该函数将text补足为8的倍数 while len(text) % 8 != 0: text += ' ' return text key = b'b4@uF1/=' # 密钥为8位或16位,必须为bytes des = DES.new(key, DES.MODE_ECB) # 创建一个DES实例 text = getText(docu) padded_text = pad(text) encrypted_text = des.encrypt(padded_text.encode('utf-8')) # 加密
-
服务器端(Server)
套接字函数
import socket ip_port = ('127.0.0.1', 8080) back_log = 5 buffer_size = 1024 #创建一个TCP套接字 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #套接字类型AF_INET, socket.SOCK_STREAM tcp协议,基于流式的协议 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #对socket的配置重用ip和端口号 #绑定端口号 s.bind(ip_port) #写哪个ip就要运行在哪台机器上 #设置半连接池 s.listen(back_log) #最多可以连接多少个客户端 print("服务开启成功") while 1: #阻塞等待,创建连接 con, address = s.accept() #在这个位置进行等待,监听端口号 while 1: #DES解密部分见下 #关闭服务器 s.close()
DES解密部分 && doxc文件写入
import socket from Cryptodome.Cipher import DES from docx import Document docu = r"C:UsersHPPCdesktop1813解密.docx" #文件储存路径,可以更改 key = b'b4@uF1/=' msg = con.recv(buffer_size) des = DES.new(key, DES.MODE_ECB) plain_text = des.decrypt(msg).decode().rstrip(' ') #解密 print("解密后的明文时:", plain_text) Doc = Document() Doc.add_paragraph(plain_text) Doc.save(docu) print("成功保存文件在" + docu) break
实验结果
首先准备好明文.doxc这个文件,我在这个word里放了一首我喜欢的词《钗头凤·红酥手》
然后运行Server程序,看到服务开启成功字样后,运行Client程序,可以看到
在Client界面
在Server界面
然后根据文件保存路径,我们打开解密.doxc可以看到
源代码链接
https://gitee.com/python_programming/xieyi_can20181312/tree/master/socket_shiyan
3. 实验过程中遇到的问题和解决过程
-
问题1:DES加密报错ValueError: Data must be aligned to block boundary in ECB mode
-
问题1解决方案:增加了pad函数
def pad(text): #由于加密文本text必须为8的倍数,该函数将text补足为8的倍数 while len(text) % 8 != 0: text += ' ' return text
其他(感悟、思考等)
Socket编程的精妙之处远不止表面这些,我最近同时也在学习Java网络编程,发现两者有很多相似之处,python的Socket编程学习使我上手Java网络编程更快一步。