课程:《Python程序设计》
班级:2133
姓名:李鹏宇
学号:20213306
实验教师:王志强
实验日期:2022年4月21日
必修/选修: 公选课
创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
import socket import datetime#以当前日期加密 from Crypto.Cipher import AES from binascii import b2a_hex, a2b_hex class AesCrypto():#支持中文的AES def __init__(self, key, IV): self.key = key #需为16位倍数 self.iv = IV #必须为16位 self.mode = AES.MODE_CBC def encrypt(self, text): cryptor = AES.new(self.key, self.mode, self.iv) length = 16 count = len(text) if(count%length != 0): add = length-(count%length) else: add=0 text = text+("\0".encode()*add)#因为中文位数原因,这里需要.encode self.ciphertext = cryptor.encrypt(text) return (self.ciphertext) def decrypt(self, text): cryptor = AES.new(self.key, self.mode, self.iv) plain_text = cryptor.decrypt((text)).decode() return plain_text s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) print("欢迎来到客户端") port = input("请输入连接端口号") s.connect(('localhost',int(port))) #暂时本地传输本地 mo = input("请选择模式\n1.文字2.传输文件") if mo == '1': s.sendall(mo.encode()) str1 = input("请输入传输内容") k = datetime.date.today() key1 = k.__format__('%Y&%m&%d%j%U%w').encode() mo1 = AesCrypto(key=key1, IV=key1) str1 = mo1.encrypt(str1.encode()) s.sendall(str1) data = s.recv(1024) print(data.decode()) elif mo == '2':#文件传输 s.sendall(mo.encode()) mo2mo = input("新建文件请输入1,传输已有文件请输入2") addre = input("请输入文件路径") k = datetime.date.today() key1 = k.__format__('%Y&%m&%d%j%U%w').encode() mo2 = AesCrypto(key=key1, IV=key1) addre1 = mo2.encrypt(addre.encode()) s.sendall(addre1) if mo2mo == "1": file1 = open(addre,"w+",encoding="utf-8")#新建文件 neirong = input("请输入内容") file1.write(neirong) file1.close() file1 = open(addre,"r",encoding="utf-8") elif mo2mo == "2": file1 = open(addre,"r",encoding="utf-8")#只读 file1.seek(0) str1 = file1.readlines() file1.close() lenfile = len(str1)#获取文件有几行 lenfile = str(lenfile) k = datetime.date.today() key1 = k.__format__('%Y&%m&%d%j%U%w').encode() mo2 = AesCrypto(key=key1, IV=key1) lenfile = mo2.encrypt(lenfile.encode())#将文件行数发出去 s.sendall(lenfile) for i in str1:#对于文件的每一行顺序发送 k = datetime.date.today() key1 = k.__format__('%Y&%m&%d%j%U%w').encode() mo2 = AesCrypto(key=key1, IV=key1) i = mo2.encrypt(i.encode()) s.sendall(i) data = s.recv(1024)#接收“已收到”信息 print(data.decode()) s.close
import socket import datetime from Crypto.Cipher import AES from binascii import b2a_hex, a2b_hex class AesCrypto(): def __init__(self, key, IV): self.key = key self.iv = IV self.mode = AES.MODE_CBC def encrypt(self, text): cryptor = AES.new(self.key, self.mode, self.iv) length = 16 count = len(text) if(count%length != 0): add = length-(count%length) else: add=0 text = text+("\0".encode()*add) self.ciphertext = cryptor.encrypt(text) return (self.ciphertext) def decrypt(self, text): cryptor = AES.new(self.key, self.mode, self.iv) plain_text = cryptor.decrypt((text)).decode('utf8','ignore') return plain_text#加密解密同理 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) port = input("欢迎使用服务端\n请输入开放连接端口号") s.bind(("localhost", int(port)))#这里只写端口号没问题 s.listen() con,addr= s.accept() mo = con.recv(1024) if mo.decode()== '1': print("已收到文字传输请求,对方正在输入...") data = con.recv(1024) k = datetime.date.today() key1 = k.__format__('%Y&%m&%d%j%U%w').encode() mo1 = AesCrypto(key=key1, IV=key1) data = mo1.decrypt(data) print(data) right = "信息已收到"#类似状态码,就没有加密 con.sendall(right.encode()) elif mo.decode()=='2': print("已收到文件传输请求,对方正在输入...") addre = con.recv(1024) k = datetime.date.today() key1 = k.__format__('%Y&%m&%d%j%U%w').encode() mo2 = AesCrypto(key=key1, IV=key1) addre = mo2.decrypt(addre) addre = addre.encode() addre = addre.split(b"\x00")[0].decode("utf-8")#防‘\’导致打开文件不存在的问题 file1 = open(addre+"1.txt","w+",encoding="utf-8")#为测试方便多加了后缀 lenfile1 = con.recv(1024) k = datetime.date.today() key1 = k.__format__('%Y&%m&%d%j%U%w').encode() mo2 = AesCrypto(key=key1, IV=key1) lenfile1 = mo2.decrypt(lenfile1) lenfile1 = lenfile1.encode() lenfile1 = lenfile1.split(b"\x00")[0].decode("utf-8") lenfile1 = int(lenfile1)#解码文件行数 for temp in range(1,lenfile1+1): temp = con.recv(1024) k = datetime.date.today() key1 = k.__format__('%Y&%m&%d%j%U%w').encode() mo2 = AesCrypto(key=key1, IV=key1) temp = mo2.decrypt(temp) temp = temp.encode() temp = temp.split(b"\x00")[0].decode("utf-8")#防字符串解密问题 print(temp)#显示一下内容 file1.write(temp)#写入文件 file1.close() right = "文件传输完成" con.sendall(right.encode()) print("文件已接收") s.close
这次实验中,我在aes加解密和bytes与str类型转换上耗费了大量的时间,这次实验让我意识到了尽管python的变量开始时是自适应的,但每个函数要求的变量不是能够通过简单的强制转换就能满足的,有时即使用正确的方式也会得到错误的结果。应该善用调试,灵活的去判断传输时每个变量的具体情况。同时,对于file方法掌握仍然不熟练,尤其是常常分不清某时指针的位置,是否创建了新文件等等,在以后会更加深入的去了解。