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("明文经加密后发送的加密文本是:\n", 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:\Users\HPPC\desktop\1813\明文.docx" #文件储存路径,可以更改
def getText(filename):
#函数将word文档中的文本以字符串形式呈现
doc = Document(filename)
fullText = ""
for para in doc.paragraphs:
fullText = fullText + para.text + '\n'
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:\Users\HPPC\desktop\1813\解密.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可以看到
源代码链接
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网络编程更快一步。
参考资料